@tsed/di 8.16.0-rc.2 → 8.16.0-rc.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/esm/common/services/DIConfiguration.js +20 -6
- package/lib/esm/common/services/InjectorService.js +3 -7
- package/lib/types/common/decorators/configuration.d.ts +1 -1
- package/lib/types/common/fn/configuration.d.ts +1 -1
- package/lib/types/common/interfaces/DIConfigurationOptions.d.ts +0 -7
- package/lib/types/common/services/DIConfiguration.d.ts +5 -7
- package/lib/types/common/services/InjectorService.d.ts +1 -2
- package/package.json +7 -7
- package/readme.md +118 -31
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getValue } from "@tsed/core/utils/getValue.js";
|
|
2
|
+
import { isFunction } from "@tsed/core/utils/isFunction.js";
|
|
2
3
|
import { setValue } from "@tsed/core/utils/setValue.js";
|
|
3
|
-
|
|
4
|
+
import { $alter } from "@tsed/hooks";
|
|
4
5
|
export class DIConfiguration {
|
|
5
6
|
constructor(initialProps = {}) {
|
|
6
7
|
this.default = new Map();
|
|
@@ -8,6 +9,7 @@ export class DIConfiguration {
|
|
|
8
9
|
Object.entries({
|
|
9
10
|
imports: [],
|
|
10
11
|
routes: [],
|
|
12
|
+
mount: {},
|
|
11
13
|
logger: {},
|
|
12
14
|
...initialProps
|
|
13
15
|
}).forEach(([key, value]) => {
|
|
@@ -57,6 +59,12 @@ export class DIConfiguration {
|
|
|
57
59
|
set debug(debug) {
|
|
58
60
|
this.logger = { ...this.logger, level: debug ? "debug" : "info" };
|
|
59
61
|
}
|
|
62
|
+
get mount() {
|
|
63
|
+
return this.get("mount");
|
|
64
|
+
}
|
|
65
|
+
set mount(value) {
|
|
66
|
+
this.setRaw("mount", value);
|
|
67
|
+
}
|
|
60
68
|
/**
|
|
61
69
|
*
|
|
62
70
|
* @param callbackfn
|
|
@@ -67,13 +75,9 @@ export class DIConfiguration {
|
|
|
67
75
|
callbackfn(this.getRaw(key), key, this.map);
|
|
68
76
|
}, thisArg);
|
|
69
77
|
}
|
|
70
|
-
/**
|
|
71
|
-
*
|
|
72
|
-
* @param propertyKey
|
|
73
|
-
* @param value
|
|
74
|
-
*/
|
|
75
78
|
set(propertyKey, value) {
|
|
76
79
|
if (typeof propertyKey === "string") {
|
|
80
|
+
value = $alter(`$alterConfig:${propertyKey}`, value);
|
|
77
81
|
if (Reflect.has(this, propertyKey)) {
|
|
78
82
|
// @ts-ignore
|
|
79
83
|
this[propertyKey] = value;
|
|
@@ -102,6 +106,16 @@ export class DIConfiguration {
|
|
|
102
106
|
get(propertyKey, defaultValue) {
|
|
103
107
|
return this.getRaw(propertyKey, defaultValue);
|
|
104
108
|
}
|
|
109
|
+
decorate(key, value) {
|
|
110
|
+
if (key in this) {
|
|
111
|
+
return this;
|
|
112
|
+
}
|
|
113
|
+
Object.defineProperty(DIConfiguration.prototype, key, isFunction(value)
|
|
114
|
+
? {
|
|
115
|
+
value
|
|
116
|
+
}
|
|
117
|
+
: value);
|
|
118
|
+
}
|
|
105
119
|
getRaw(propertyKey, defaultValue) {
|
|
106
120
|
const value = getValue(this.map, propertyKey);
|
|
107
121
|
if (value !== undefined) {
|
|
@@ -46,17 +46,13 @@ export class InjectorService extends Container {
|
|
|
46
46
|
constructor() {
|
|
47
47
|
super();
|
|
48
48
|
this.logger = console;
|
|
49
|
+
/*readonly */
|
|
50
|
+
this.settings = new DIConfiguration();
|
|
49
51
|
this.resolvedConfiguration = false;
|
|
50
52
|
this.#cache = new LocalsContainer();
|
|
51
53
|
this.#loaded = false;
|
|
52
54
|
this.#cache.set(InjectorService, this);
|
|
53
|
-
this.#cache.set(DIConfiguration,
|
|
54
|
-
}
|
|
55
|
-
get settings() {
|
|
56
|
-
return this.#cache.get(DIConfiguration);
|
|
57
|
-
}
|
|
58
|
-
set settings(settings) {
|
|
59
|
-
this.#cache.set(DIConfiguration, settings);
|
|
55
|
+
this.#cache.set(DIConfiguration, this.settings);
|
|
60
56
|
}
|
|
61
57
|
isLoaded() {
|
|
62
58
|
return this.#loaded;
|
|
@@ -6,4 +6,4 @@ import { DIConfiguration } from "../services/DIConfiguration.js";
|
|
|
6
6
|
*/
|
|
7
7
|
export declare function Configuration(): any;
|
|
8
8
|
export declare function Configuration(settings: Partial<TsED.Configuration>): ClassDecorator;
|
|
9
|
-
export type Configuration = TsED.
|
|
9
|
+
export type Configuration = TsED.Configuration & DIConfiguration;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TokenProvider } from "../interfaces/TokenProvider.js";
|
|
2
2
|
import { DIConfiguration } from "../services/DIConfiguration.js";
|
|
3
|
-
export declare function configuration(): TsED.
|
|
3
|
+
export declare function configuration(): TsED.Configuration & DIConfiguration;
|
|
4
4
|
export declare function configuration(token: TokenProvider): Partial<TsED.Configuration>;
|
|
5
5
|
export declare function configuration(token: TokenProvider, configuration: Partial<TsED.Configuration>): Partial<TsED.Configuration>;
|
|
@@ -5,11 +5,6 @@ declare global {
|
|
|
5
5
|
namespace TsED {
|
|
6
6
|
interface Context {
|
|
7
7
|
}
|
|
8
|
-
/**
|
|
9
|
-
* Here to allow extension on DIConfiguration base service
|
|
10
|
-
*/
|
|
11
|
-
interface DIConfiguration {
|
|
12
|
-
}
|
|
13
8
|
interface Configuration extends Record<string, any> {
|
|
14
9
|
scopes: {
|
|
15
10
|
[key: string]: ProviderScope;
|
|
@@ -25,5 +20,3 @@ declare global {
|
|
|
25
20
|
}
|
|
26
21
|
}
|
|
27
22
|
}
|
|
28
|
-
export interface DIConfigurationOptions extends TsED.Configuration {
|
|
29
|
-
}
|
|
@@ -3,7 +3,6 @@ import type { DILoggerOptions } from "../interfaces/DILoggerOptions.js";
|
|
|
3
3
|
import type { ImportTokenProviderOpts } from "../interfaces/ImportTokenProviderOpts.js";
|
|
4
4
|
import type { TokenProvider } from "../interfaces/TokenProvider.js";
|
|
5
5
|
import type { TokenRoute } from "../interfaces/TokenRoute.js";
|
|
6
|
-
export declare const CONFIGURATION: unique symbol;
|
|
7
6
|
export declare class DIConfiguration {
|
|
8
7
|
readonly default: Map<string, any>;
|
|
9
8
|
protected map: Map<string, any>;
|
|
@@ -22,18 +21,16 @@ export declare class DIConfiguration {
|
|
|
22
21
|
set logger(value: Partial<DILoggerOptions>);
|
|
23
22
|
get debug(): boolean;
|
|
24
23
|
set debug(debug: boolean);
|
|
24
|
+
get mount(): Record<string, TokenProvider[]>;
|
|
25
|
+
set mount(value: Record<string, TokenProvider[]>);
|
|
25
26
|
/**
|
|
26
27
|
*
|
|
27
28
|
* @param callbackfn
|
|
28
29
|
* @param thisArg
|
|
29
30
|
*/
|
|
30
31
|
forEach(callbackfn: (value: any, index: string, map: Map<string, any>) => void, thisArg?: any): void;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
* @param propertyKey
|
|
34
|
-
* @param value
|
|
35
|
-
*/
|
|
36
|
-
set(propertyKey: string | Partial<TsED.Configuration>, value?: any): this;
|
|
32
|
+
set(obj: Partial<TsED.Configuration>): this;
|
|
33
|
+
set(propertyKey: string, value?: unknown): this;
|
|
37
34
|
setRaw(propertyKey: string, value: any): this;
|
|
38
35
|
/**
|
|
39
36
|
*
|
|
@@ -42,5 +39,6 @@ export declare class DIConfiguration {
|
|
|
42
39
|
* @returns {undefined|any}
|
|
43
40
|
*/
|
|
44
41
|
get<T = any>(propertyKey: string, defaultValue?: T): T;
|
|
42
|
+
decorate(key: string, value: ((...args: unknown[]) => unknown) | PropertyDescriptor): this | undefined;
|
|
45
43
|
protected getRaw(propertyKey: string, defaultValue?: any): any;
|
|
46
44
|
}
|
|
@@ -27,10 +27,9 @@ import { DIConfiguration } from "./DIConfiguration.js";
|
|
|
27
27
|
export declare class InjectorService extends Container {
|
|
28
28
|
#private;
|
|
29
29
|
logger: DILogger;
|
|
30
|
+
settings: DIConfiguration;
|
|
30
31
|
private resolvedConfiguration;
|
|
31
32
|
constructor();
|
|
32
|
-
get settings(): DIConfiguration;
|
|
33
|
-
set settings(settings: DIConfiguration);
|
|
34
33
|
isLoaded(): boolean;
|
|
35
34
|
/**
|
|
36
35
|
* Return a list of instance build by the injector.
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@tsed/di",
|
|
3
3
|
"description": "DI module for Ts.ED Framework",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "8.16.0-rc.
|
|
5
|
+
"version": "8.16.0-rc.4",
|
|
6
6
|
"source": "./src/index.ts",
|
|
7
7
|
"main": "./lib/esm/index.js",
|
|
8
8
|
"module": "./lib/esm/index.js",
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
"uuid": "^10.0.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@tsed/barrels": "8.16.0-rc.
|
|
33
|
-
"@tsed/core": "8.16.0-rc.
|
|
34
|
-
"@tsed/hooks": "8.16.0-rc.
|
|
35
|
-
"@tsed/logger": "^8.0.0
|
|
36
|
-
"@tsed/typescript": "8.16.0-rc.
|
|
32
|
+
"@tsed/barrels": "8.16.0-rc.4",
|
|
33
|
+
"@tsed/core": "8.16.0-rc.4",
|
|
34
|
+
"@tsed/hooks": "8.16.0-rc.4",
|
|
35
|
+
"@tsed/logger": "^8.0.0",
|
|
36
|
+
"@tsed/typescript": "8.16.0-rc.4",
|
|
37
37
|
"cross-env": "7.0.3",
|
|
38
38
|
"eslint": "9.12.0",
|
|
39
39
|
"typescript": "5.4.5",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"@tsed/core": ">=8.0.0",
|
|
45
45
|
"@tsed/hooks": ">=8.0.0",
|
|
46
|
-
"@tsed/logger": ">=8.0.0
|
|
46
|
+
"@tsed/logger": ">=8.0.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependenciesMeta": {
|
|
49
49
|
"@tsed/core": {
|
package/readme.md
CHANGED
|
@@ -36,7 +36,9 @@
|
|
|
36
36
|
<code><img height="20" src="https://raw.githubusercontent.com/github/explore/80688e429a7d4ef2fca1e82350fe8e3517d3494d/topics/chrome/chrome.png"></code>
|
|
37
37
|
<code><img height="20" src="https://raw.githubusercontent.com/github/explore/80688e429a7d4ef2fca1e82350fe8e3517d3494d/topics/react/react.png"></code>
|
|
38
38
|
|
|
39
|
-
A powerful and flexible Dependency Injection (DI) toolkit inspired by Angular, designed for both TypeScript and pure
|
|
39
|
+
A powerful and flexible Dependency Injection (DI) toolkit inspired by Angular, designed for both TypeScript and pure
|
|
40
|
+
JavaScript applications. Use it standalone or as the foundation of Ts.ED. Supports both decorator-based and functional (
|
|
41
|
+
decorator-less) APIs for maximum compatibility, even in non-TypeScript or pure JS projects.
|
|
40
42
|
|
|
41
43
|
---
|
|
42
44
|
|
|
@@ -59,15 +61,26 @@ npm install --save @tsed/di @tsed/core @tsed/hooks @tsed/logger
|
|
|
59
61
|
|
|
60
62
|
## Features
|
|
61
63
|
|
|
62
|
-
- **[Providers](https://tsed.dev/docs/providers.html):** Register and manage services, factories, values, interceptors,
|
|
63
|
-
|
|
64
|
-
- **[
|
|
65
|
-
|
|
66
|
-
- **[
|
|
67
|
-
|
|
68
|
-
- **[
|
|
69
|
-
|
|
70
|
-
- **[
|
|
64
|
+
- **[Providers](https://tsed.dev/docs/providers.html):** Register and manage services, factories, values, interceptors,
|
|
65
|
+
and more.
|
|
66
|
+
- **[Functional API](https://tsed.dev/docs/providers.html#injectable):** Register providers and factories without
|
|
67
|
+
decorators (for pure JS or decorator-less code).
|
|
68
|
+
- **[Async Factories](https://tsed.dev/docs/custom-providers.html#register-async-factory):** Create providers that
|
|
69
|
+
resolve asynchronously (e.g., database connections).
|
|
70
|
+
- **[Constants Injection](https://tsed.dev/docs/providers.html#constant):** Use `@Constant()` or `constant()` to inject
|
|
71
|
+
configuration or static values.
|
|
72
|
+
- **[Value Injection](https://tsed.dev/docs/providers.html#value-refvalue):** Use `@Value()` or `refValue()` to inject
|
|
73
|
+
resolved provider values.
|
|
74
|
+
- **[InjectContext](https://tsed.dev/docs/providers.html#inject-context):** Access the injection context and advanced DI
|
|
75
|
+
features.
|
|
76
|
+
- **[Config Sources](https://tsed.dev/docs/configuration/configuration-sources.html):** Load and merge configuration
|
|
77
|
+
from multiple sources (files, env, remote, etc.).
|
|
78
|
+
- **[Lifecycle hooks](https://tsed.dev/docs/hooks.html):** Manage provider lifecycle with hooks like `$onInit`,
|
|
79
|
+
`$onDestroy`.
|
|
80
|
+
- **[Lazy loading](https://tsed.dev/docs/providers.html#lazy-load-provider):** Lazily load Node.js ESM modules. The lazy
|
|
81
|
+
loading feature allows you to declare a provider that is only instantiated when it is first injected. The DI system
|
|
82
|
+
will dynamically import the ESM module, discover injectable services within it, and instantiate them on
|
|
83
|
+
demand—enabling efficient code splitting and reducing startup time.
|
|
71
84
|
- **Full TypeScript support:** Type inference with `inject()` and advanced tooling for type-safe DI.
|
|
72
85
|
|
|
73
86
|
---
|
|
@@ -118,7 +131,8 @@ You can use it in any JS/TS project (web, CLI, backend, etc) without Ts.ED.
|
|
|
118
131
|
|
|
119
132
|
## Stable & Recommended Initialization Example
|
|
120
133
|
|
|
121
|
-
This is the recommended and most stable way to initialize and use the injector, especially when working with advanced
|
|
134
|
+
This is the recommended and most stable way to initialize and use the injector, especially when working with advanced
|
|
135
|
+
scenarios (settings, async providers, custom loggers, etc):
|
|
122
136
|
|
|
123
137
|
```typescript
|
|
124
138
|
import {injector, attachLogger, inject} from "@tsed/di";
|
|
@@ -127,12 +141,6 @@ import {CalendarCtrl} from "./CalendarCtrl.js";
|
|
|
127
141
|
|
|
128
142
|
// Create a new InjectorService instance
|
|
129
143
|
const inj = injector();
|
|
130
|
-
|
|
131
|
-
// Register your configuration provider
|
|
132
|
-
inj.addProvider(PlatformConfiguration);
|
|
133
|
-
|
|
134
|
-
// Optionally invoke and set configuration
|
|
135
|
-
inj.settings = inj.invoke(PlatformConfiguration);
|
|
136
144
|
inj.settings.set(settings);
|
|
137
145
|
|
|
138
146
|
// Attach a custom logger (optional)
|
|
@@ -198,11 +206,6 @@ import "./services/GetAllowerUsers.js"; // just add import is enough to discover
|
|
|
198
206
|
// Create a new InjectorService instance
|
|
199
207
|
const inj = injector();
|
|
200
208
|
|
|
201
|
-
// Register your configuration provider
|
|
202
|
-
inj.addProvider(PlatformConfiguration);
|
|
203
|
-
|
|
204
|
-
// Optionally invoke and set configuration
|
|
205
|
-
inj.settings = inj.invoke(PlatformConfiguration);
|
|
206
209
|
inj.settings.set(settings);
|
|
207
210
|
|
|
208
211
|
// Attach a custom logger (optional)
|
|
@@ -213,9 +216,11 @@ attachLogger($log); // Overriding the default logger is not recommended
|
|
|
213
216
|
await inj.load();
|
|
214
217
|
```
|
|
215
218
|
|
|
216
|
-
The example above is the main point to start the DI system. It should be placed in the main entry file of your
|
|
219
|
+
The example above is the main point to start the DI system. It should be placed in the main entry file of your
|
|
220
|
+
application.
|
|
217
221
|
|
|
218
|
-
Now, you can use the `inject()` function to retrieve the instance of the class, injectable provider, or pure JavaScript
|
|
222
|
+
Now, you can use the `inject()` function to retrieve the instance of the class, injectable provider, or pure JavaScript
|
|
223
|
+
function.
|
|
219
224
|
|
|
220
225
|
For example, if you want to use the `GET_ALLOWED_USERS` factory in your application, you can do it like this:
|
|
221
226
|
|
|
@@ -246,7 +251,8 @@ In summary:
|
|
|
246
251
|
|
|
247
252
|
## Async Factories
|
|
248
253
|
|
|
249
|
-
You can register **async factories** to provide values/services that require asynchronous initialization (e.g., database
|
|
254
|
+
You can register **async factories** to provide values/services that require asynchronous initialization (e.g., database
|
|
255
|
+
connections):
|
|
250
256
|
|
|
251
257
|
```typescript
|
|
252
258
|
import {injectable, inject} from "@tsed/di";
|
|
@@ -269,7 +275,8 @@ db.query("SELECT * FROM users");
|
|
|
269
275
|
|
|
270
276
|
## Injecting Constants with `@Constant()` and `@Value()`
|
|
271
277
|
|
|
272
|
-
You can inject constant values or configuration using the `@Constant()` decorator (or `constant()` function in the
|
|
278
|
+
You can inject constant values or configuration using the `@Constant()` decorator (or `constant()` function in the
|
|
279
|
+
Functional API):
|
|
273
280
|
|
|
274
281
|
```typescript
|
|
275
282
|
import {Injectable, Constant} from "@tsed/di";
|
|
@@ -284,7 +291,8 @@ export class MyService {
|
|
|
284
291
|
}
|
|
285
292
|
```
|
|
286
293
|
|
|
287
|
-
You can also use `@Value()` to inject the resolved value of a provider (by token), or `refValue()` for the functional
|
|
294
|
+
You can also use `@Value()` to inject the resolved value of a provider (by token), or `refValue()` for the functional
|
|
295
|
+
API:
|
|
288
296
|
|
|
289
297
|
```typescript
|
|
290
298
|
import {Injectable, Value} from "@tsed/di";
|
|
@@ -331,6 +339,77 @@ See [Providers documentation](https://tsed.dev/docs/providers.html).
|
|
|
331
339
|
|
|
332
340
|
---
|
|
333
341
|
|
|
342
|
+
## Extending DIConfiguration
|
|
343
|
+
|
|
344
|
+
The `DIConfiguration` class provides a `decorate` method that allows you to extend its functionality by adding new methods or properties. You can access this method through the `configuration()` function.
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
import {configuration} from "@tsed/di";
|
|
348
|
+
|
|
349
|
+
// Add a custom method to DIConfiguration
|
|
350
|
+
configuration().decorate("myCustomMethod", function () {
|
|
351
|
+
// Your custom logic here
|
|
352
|
+
return "Custom result";
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// Usage
|
|
356
|
+
const result = configuration().myCustomMethod(); // "Custom result"
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
You can also add a property with a custom getter/setter:
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
configuration().decorate("customProperty", {
|
|
363
|
+
get() {
|
|
364
|
+
return this.get("someInternalValue");
|
|
365
|
+
},
|
|
366
|
+
set(value) {
|
|
367
|
+
this.set("someInternalValue", value);
|
|
368
|
+
}
|
|
369
|
+
});
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
This is particularly useful for plugin authors who want to extend the configuration capabilities without modifying the core code.
|
|
373
|
+
|
|
374
|
+
---
|
|
375
|
+
|
|
376
|
+
## Using the $alterConfig:propertyKey Hook
|
|
377
|
+
|
|
378
|
+
The `$alterConfig:propertyKey` hook allows you to intercept and modify configuration values before they are assigned to a property. This is useful when you need to transform, validate, or augment configuration values dynamically.
|
|
379
|
+
|
|
380
|
+
When a value is set in the configuration using the `set()` method, the DIConfiguration class internally calls the `$alter` hook with the pattern `$alterConfig:${propertyKey}`, passing the value as the second argument.
|
|
381
|
+
|
|
382
|
+
Here's how to use this hook:
|
|
383
|
+
|
|
384
|
+
```typescript
|
|
385
|
+
import {$on} from "@tsed/hooks";
|
|
386
|
+
|
|
387
|
+
// Register a hook to intercept and modify the 'jsonMapper' configuration
|
|
388
|
+
$on("$alterConfig:jsonMapper", (options) => {
|
|
389
|
+
// Modify the options before they are assigned
|
|
390
|
+
options.strictGroups = Boolean(options.strictGroups);
|
|
391
|
+
options.disableUnsecureConstructor = Boolean(options.disableUnsecureConstructor);
|
|
392
|
+
options.additionalProperties = Boolean(
|
|
393
|
+
isBoolean(options.additionalProperties) ? options.additionalProperties : options.additionalProperties === "accept"
|
|
394
|
+
);
|
|
395
|
+
|
|
396
|
+
// Return the modified options
|
|
397
|
+
return options;
|
|
398
|
+
});
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
This hook is particularly useful for:
|
|
402
|
+
|
|
403
|
+
- Normalizing configuration values
|
|
404
|
+
- Applying default values
|
|
405
|
+
- Validating configuration before it's applied
|
|
406
|
+
- Transforming configuration formats
|
|
407
|
+
- Implementing cross-cutting concerns for configuration properties
|
|
408
|
+
|
|
409
|
+
The hook is executed whenever the corresponding property is set, whether through direct assignment or through the `configuration().set()` method.
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
334
413
|
## Documentation & Resources
|
|
335
414
|
|
|
336
415
|
- **[Providers](https://tsed.dev/docs/providers.html)**
|
|
@@ -354,7 +433,8 @@ Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com
|
|
|
354
433
|
|
|
355
434
|
## Sponsors
|
|
356
435
|
|
|
357
|
-
Support this project by becoming a sponsor. Your logo will show up here with a link to your
|
|
436
|
+
Support this project by becoming a sponsor. Your logo will show up here with a link to your
|
|
437
|
+
website. [[Become a sponsor](https://opencollective.com/tsed#sponsor)]
|
|
358
438
|
|
|
359
439
|
## License
|
|
360
440
|
|
|
@@ -362,8 +442,15 @@ The MIT License (MIT)
|
|
|
362
442
|
|
|
363
443
|
Copyright (c) 2016 - 2022 Romain Lenzotti
|
|
364
444
|
|
|
365
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
445
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
|
446
|
+
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
|
447
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
|
448
|
+
persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
366
449
|
|
|
367
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
|
450
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
|
451
|
+
Software.
|
|
368
452
|
|
|
369
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
453
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
454
|
+
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
455
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
456
|
+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|