awilix 5.0.1 → 6.0.0
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/README.md +15 -17
- package/lib/awilix.browser.js +74 -61
- package/lib/awilix.module.js +73 -58
- package/lib/awilix.umd.js +76 -63
- package/lib/container.d.ts +16 -3
- package/lib/container.js +55 -50
- package/lib/container.js.map +1 -1
- package/lib/function-tokenizer.js +2 -2
- package/lib/injection-mode.js.map +1 -1
- package/lib/list-modules.js +2 -2
- package/lib/list-modules.js.map +1 -1
- package/lib/load-modules.js +6 -6
- package/lib/load-modules.js.map +1 -1
- package/lib/param-parser.d.ts +1 -1
- package/lib/param-parser.js +10 -3
- package/lib/param-parser.js.map +1 -1
- package/lib/resolvers.js +15 -12
- package/lib/resolvers.js.map +1 -1
- package/lib/utils.d.ts +2 -2
- package/lib/utils.js +3 -3
- package/lib/utils.js.map +1 -1
- package/package.json +19 -20
package/README.md
CHANGED
|
@@ -53,7 +53,7 @@ written in [TypeScript](http://typescriptlang.org). **Make IoC great again!**
|
|
|
53
53
|
- [`container.build()`](#containerbuild)
|
|
54
54
|
- [`container.dispose()`](#containerdispose)
|
|
55
55
|
- [Universal Module (Browser Support)](#universal-module-browser-support)
|
|
56
|
-
- [Contributing](#contributing)
|
|
56
|
+
- [Contributing](#contributing)
|
|
57
57
|
- [What's in a name?](#whats-in-a-name)
|
|
58
58
|
- [Author](#author)
|
|
59
59
|
|
|
@@ -351,8 +351,12 @@ modes are available on `awilix.InjectionMode`
|
|
|
351
351
|
```
|
|
352
352
|
|
|
353
353
|
- `InjectionMode.CLASSIC`: Parses the function/constructor parameters, and
|
|
354
|
-
matches them with registrations in the container.
|
|
355
|
-
|
|
354
|
+
matches them with registrations in the container. `CLASSIC` mode has a
|
|
355
|
+
slightly higher initialization cost as it has to parse the function/class
|
|
356
|
+
to figure out the dependencies at the time of registration, however resolving
|
|
357
|
+
them will be **much faster** than when using `PROXY`. _Don't use `CLASSIC` if
|
|
358
|
+
you minify your code!_ We recommend using `CLASSIC` in Node and `PROXY` in
|
|
359
|
+
environments where minification is needed.
|
|
356
360
|
|
|
357
361
|
```js
|
|
358
362
|
class UserService {
|
|
@@ -363,7 +367,8 @@ modes are available on `awilix.InjectionMode`
|
|
|
363
367
|
}
|
|
364
368
|
```
|
|
365
369
|
|
|
366
|
-
Additionally, if the class has a base class but does not
|
|
370
|
+
Additionally, if the class has a base class but does not declare a constructor of its own, Awilix
|
|
371
|
+
simply invokes the base constructor with whatever dependencies it requires.
|
|
367
372
|
|
|
368
373
|
```js
|
|
369
374
|
class Car {
|
|
@@ -373,9 +378,8 @@ modes are available on `awilix.InjectionMode`
|
|
|
373
378
|
}
|
|
374
379
|
|
|
375
380
|
class Porsche extends Car {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
console.log(arguments[0]) // whatever "engine" is
|
|
381
|
+
vroom() {
|
|
382
|
+
console.log(this.engine) // whatever "engine" is
|
|
379
383
|
}
|
|
380
384
|
}
|
|
381
385
|
```
|
|
@@ -1064,7 +1068,8 @@ Args:
|
|
|
1064
1068
|
pass the name through as-is. The 2nd parameter is a full module descriptor.
|
|
1065
1069
|
- `opts.resolverOptions`: An `object` passed to the resolvers. Used to configure
|
|
1066
1070
|
the lifetime, injection mode and more of the loaded modules.
|
|
1067
|
-
- `opts.esModules`: Loads modules using Node's native ES modules. This is only
|
|
1071
|
+
- `opts.esModules`: Loads modules using Node's native ES modules. This is only
|
|
1072
|
+
supported on Node 14.0+ and should only be used if you're using the [Native Node ES modules](https://nodejs.org/api/esm.html)
|
|
1068
1073
|
|
|
1069
1074
|
Example:
|
|
1070
1075
|
|
|
@@ -1337,16 +1342,9 @@ because they depend on Node-specific packages.
|
|
|
1337
1342
|
- Safari >= 10
|
|
1338
1343
|
- Internet Explorer is not supported
|
|
1339
1344
|
|
|
1340
|
-
|
|
1345
|
+
## Contributing
|
|
1341
1346
|
|
|
1342
|
-
|
|
1343
|
-
`npm run test -- --watchAll` to start writing code.
|
|
1344
|
-
|
|
1345
|
-
For code coverage, run `npm run cover`.
|
|
1346
|
-
|
|
1347
|
-
If you submit a PR, please aim for 100% code coverage and no linting errors.
|
|
1348
|
-
Travis will fail if there are linting errors. Thank you for considering
|
|
1349
|
-
contributing. :)
|
|
1347
|
+
Please see our [contributing.md](./CONTRIBUTING.md)
|
|
1350
1348
|
|
|
1351
1349
|
# What's in a name?
|
|
1352
1350
|
|
package/lib/awilix.browser.js
CHANGED
|
@@ -416,7 +416,7 @@ function createTokenizer(source) {
|
|
|
416
416
|
* Determines if the given character is a whitespace character.
|
|
417
417
|
*
|
|
418
418
|
* @param {string} ch
|
|
419
|
-
* @return {
|
|
419
|
+
* @return {boolean}
|
|
420
420
|
*/
|
|
421
421
|
function isWhiteSpace(ch) {
|
|
422
422
|
switch (ch) {
|
|
@@ -430,7 +430,7 @@ function isWhiteSpace(ch) {
|
|
|
430
430
|
/**
|
|
431
431
|
* Determines if the specified character is a string quote.
|
|
432
432
|
* @param {string} ch
|
|
433
|
-
* @return {
|
|
433
|
+
* @return {boolean}
|
|
434
434
|
*/
|
|
435
435
|
function isStringQuote(ch) {
|
|
436
436
|
switch (ch) {
|
|
@@ -494,7 +494,7 @@ function last(arr) {
|
|
|
494
494
|
* Determines if the given function is a class.
|
|
495
495
|
*
|
|
496
496
|
* @param {Function} fn
|
|
497
|
-
* @return {
|
|
497
|
+
* @return {boolean}
|
|
498
498
|
*/
|
|
499
499
|
function isClass(fn) {
|
|
500
500
|
/*tslint:disable-next-line*/
|
|
@@ -521,7 +521,7 @@ function isClass(fn) {
|
|
|
521
521
|
* @param {Any} val
|
|
522
522
|
* Any value to check if it's a function.
|
|
523
523
|
*
|
|
524
|
-
* @return {
|
|
524
|
+
* @return {boolean}
|
|
525
525
|
* true if the value is a function, false otherwise.
|
|
526
526
|
*/
|
|
527
527
|
function isFunction(val) {
|
|
@@ -585,8 +585,9 @@ var InjectionMode = {
|
|
|
585
585
|
* @param {string} source
|
|
586
586
|
* The source of a function to extract the parameter list from
|
|
587
587
|
*
|
|
588
|
-
* @return {Array<Parameter>}
|
|
589
|
-
* Returns an array of parameters
|
|
588
|
+
* @return {Array<Parameter> | null}
|
|
589
|
+
* Returns an array of parameters, or `null` if no
|
|
590
|
+
* constructor was found for a class.
|
|
590
591
|
*/
|
|
591
592
|
function parseParameterList(source) {
|
|
592
593
|
var _a = createTokenizer(source), _next = _a.next, done = _a.done;
|
|
@@ -597,6 +598,11 @@ function parseParameterList(source) {
|
|
|
597
598
|
switch (t.type) {
|
|
598
599
|
case 'class':
|
|
599
600
|
skipUntilConstructor();
|
|
601
|
+
// If we didn't find a constructor token, then we know that there
|
|
602
|
+
// are no dependencies in the defined class.
|
|
603
|
+
if (!isConstructorToken()) {
|
|
604
|
+
return null;
|
|
605
|
+
}
|
|
600
606
|
// Next token is the constructor identifier.
|
|
601
607
|
nextToken();
|
|
602
608
|
break;
|
|
@@ -676,6 +682,7 @@ function parseParameterList(source) {
|
|
|
676
682
|
}
|
|
677
683
|
/**
|
|
678
684
|
* Determines if the current token represents a constructor, and the next token after it is a paren
|
|
685
|
+
* @return {boolean}
|
|
679
686
|
*/
|
|
680
687
|
function isConstructorToken() {
|
|
681
688
|
return t.type === 'ident' && t.value === 'constructor';
|
|
@@ -893,7 +900,7 @@ function wrapWithLocals(container, locals) {
|
|
|
893
900
|
*/
|
|
894
901
|
function createInjectorProxy(container, injector) {
|
|
895
902
|
var locals = injector(container);
|
|
896
|
-
var allKeys = uniq(__spreadArray(__spreadArray([], Reflect.ownKeys(container.cradle)), Reflect.ownKeys(locals)));
|
|
903
|
+
var allKeys = uniq(__spreadArray(__spreadArray([], Reflect.ownKeys(container.cradle), true), Reflect.ownKeys(locals)));
|
|
897
904
|
// TODO: Lots of duplication here from the container proxy.
|
|
898
905
|
// Need to refactor.
|
|
899
906
|
var proxy = new Proxy({}, {
|
|
@@ -1027,29 +1034,30 @@ function generateResolve(fn, dependencyParseTarget) {
|
|
|
1027
1034
|
}
|
|
1028
1035
|
/**
|
|
1029
1036
|
* Parses the dependencies from the given function.
|
|
1030
|
-
* If it's a class
|
|
1037
|
+
* If it's a class that extends another class, and it does
|
|
1038
|
+
* not have a defined constructor, attempt to parse it's super constructor.
|
|
1031
1039
|
*/
|
|
1032
1040
|
function parseDependencies(fn) {
|
|
1033
1041
|
var result = parseParameterList(fn.toString());
|
|
1034
|
-
if (result
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1042
|
+
if (!result) {
|
|
1043
|
+
// No defined constructor for a class, check if there is a parent
|
|
1044
|
+
// we can parse.
|
|
1045
|
+
var parent = Object.getPrototypeOf(fn);
|
|
1046
|
+
if (typeof parent === 'function' && parent !== Function.prototype) {
|
|
1047
|
+
// Try to parse the parent
|
|
1048
|
+
return parseDependencies(parent);
|
|
1049
|
+
}
|
|
1050
|
+
return [];
|
|
1041
1051
|
}
|
|
1042
1052
|
return result;
|
|
1043
1053
|
}
|
|
1044
1054
|
|
|
1045
1055
|
/**
|
|
1046
1056
|
* Family tree symbol.
|
|
1047
|
-
* @type {Symbol}
|
|
1048
1057
|
*/
|
|
1049
1058
|
var FAMILY_TREE = Symbol('familyTree');
|
|
1050
1059
|
/**
|
|
1051
1060
|
* Roll Up Registrations symbol.
|
|
1052
|
-
* @type {Symbol}
|
|
1053
1061
|
*/
|
|
1054
1062
|
var ROLL_UP_REGISTRATIONS = Symbol('rollUpRegistrations');
|
|
1055
1063
|
/**
|
|
@@ -1061,7 +1069,7 @@ var ROLL_UP_REGISTRATIONS = Symbol('rollUpRegistrations');
|
|
|
1061
1069
|
* @param {string} options.injectionMode
|
|
1062
1070
|
* The mode used by the container to resolve dependencies. Defaults to 'Proxy'.
|
|
1063
1071
|
*
|
|
1064
|
-
* @return {
|
|
1072
|
+
* @return {AwilixContainer<T>}
|
|
1065
1073
|
* The container.
|
|
1066
1074
|
*/
|
|
1067
1075
|
function createContainer(options, parentContainer) {
|
|
@@ -1072,9 +1080,6 @@ function createContainer(options, parentContainer) {
|
|
|
1072
1080
|
// an error occurs, we have something to present
|
|
1073
1081
|
// to the poor developer who fucked up.
|
|
1074
1082
|
var resolutionStack = [];
|
|
1075
|
-
// For performance reasons, we store
|
|
1076
|
-
// the rolled-up registrations when starting a resolve.
|
|
1077
|
-
var computedRegistrations = null;
|
|
1078
1083
|
// Internal registration store for this container.
|
|
1079
1084
|
var registrations = {};
|
|
1080
1085
|
/**
|
|
@@ -1088,7 +1093,7 @@ function createContainer(options, parentContainer) {
|
|
|
1088
1093
|
/**
|
|
1089
1094
|
* The `get` handler is invoked whenever a get-call for `container.cradle.*` is made.
|
|
1090
1095
|
*
|
|
1091
|
-
* @param {object}
|
|
1096
|
+
* @param {object} _target
|
|
1092
1097
|
* The proxy target. Irrelevant.
|
|
1093
1098
|
*
|
|
1094
1099
|
* @param {string} name
|
|
@@ -1097,14 +1102,14 @@ function createContainer(options, parentContainer) {
|
|
|
1097
1102
|
* @return {*}
|
|
1098
1103
|
* Whatever the resolve call returns.
|
|
1099
1104
|
*/
|
|
1100
|
-
get: function (
|
|
1105
|
+
get: function (_target, name) { return resolve(name); },
|
|
1101
1106
|
/**
|
|
1102
1107
|
* Setting things on the cradle throws an error.
|
|
1103
1108
|
*
|
|
1104
1109
|
* @param {object} target
|
|
1105
1110
|
* @param {string} name
|
|
1106
1111
|
*/
|
|
1107
|
-
set: function (_target, name
|
|
1112
|
+
set: function (_target, name) {
|
|
1108
1113
|
throw new Error("Attempted setting property \"" + name + "\" on container cradle - this is not allowed.");
|
|
1109
1114
|
},
|
|
1110
1115
|
/**
|
|
@@ -1138,8 +1143,9 @@ function createContainer(options, parentContainer) {
|
|
|
1138
1143
|
register: register,
|
|
1139
1144
|
build: build,
|
|
1140
1145
|
resolve: resolve,
|
|
1141
|
-
|
|
1142
|
-
dispose: dispose
|
|
1146
|
+
hasRegistration: hasRegistration,
|
|
1147
|
+
dispose: dispose,
|
|
1148
|
+
getRegistration: getRegistration
|
|
1143
1149
|
},
|
|
1144
1150
|
/* removed in browser build */
|
|
1145
1151
|
// tslint:disable-next-line
|
|
@@ -1164,12 +1170,15 @@ function createContainer(options, parentContainer) {
|
|
|
1164
1170
|
/**
|
|
1165
1171
|
* Used by util.inspect (which is used by console.log).
|
|
1166
1172
|
*/
|
|
1167
|
-
function inspect(
|
|
1173
|
+
function inspect() {
|
|
1168
1174
|
return "[AwilixContainer (" + (parentContainer ? 'scoped, ' : '') + "registrations: " + Object.keys(container.registrations).length + ")]";
|
|
1169
1175
|
}
|
|
1170
1176
|
/**
|
|
1171
1177
|
* Rolls up registrations from the family tree.
|
|
1172
|
-
*
|
|
1178
|
+
*
|
|
1179
|
+
* This can get pretty expensive. Only used when
|
|
1180
|
+
* iterating the cradle proxy, which is not something
|
|
1181
|
+
* that should be done in day-to-day use, mostly for debugging.
|
|
1173
1182
|
*
|
|
1174
1183
|
* @param {boolean} bustCache
|
|
1175
1184
|
* Forces a recomputation.
|
|
@@ -1177,19 +1186,13 @@ function createContainer(options, parentContainer) {
|
|
|
1177
1186
|
* @return {object}
|
|
1178
1187
|
* The merged registrations object.
|
|
1179
1188
|
*/
|
|
1180
|
-
function rollUpRegistrations(
|
|
1181
|
-
|
|
1182
|
-
if (computedRegistrations && !bustCache) {
|
|
1183
|
-
return computedRegistrations;
|
|
1184
|
-
}
|
|
1185
|
-
computedRegistrations = __assign(__assign({}, (parentContainer &&
|
|
1186
|
-
parentContainer[ROLL_UP_REGISTRATIONS](bustCache))), registrations);
|
|
1187
|
-
return computedRegistrations;
|
|
1189
|
+
function rollUpRegistrations() {
|
|
1190
|
+
return __assign(__assign({}, (parentContainer && parentContainer[ROLL_UP_REGISTRATIONS]())), registrations);
|
|
1188
1191
|
}
|
|
1189
1192
|
/**
|
|
1190
1193
|
* Used for providing an iterator to the cradle.
|
|
1191
1194
|
*/
|
|
1192
|
-
function
|
|
1195
|
+
function cradleIterator() {
|
|
1193
1196
|
var registrations, _a, _b, _i, registrationName;
|
|
1194
1197
|
return __generator(this, function (_c) {
|
|
1195
1198
|
switch (_c.label) {
|
|
@@ -1228,14 +1231,12 @@ function createContainer(options, parentContainer) {
|
|
|
1228
1231
|
*/
|
|
1229
1232
|
function register(arg1, arg2) {
|
|
1230
1233
|
var obj = nameValueToObject(arg1, arg2);
|
|
1231
|
-
var keys = __spreadArray(__spreadArray([], Object.keys(obj)), Object.getOwnPropertySymbols(obj));
|
|
1234
|
+
var keys = __spreadArray(__spreadArray([], Object.keys(obj), true), Object.getOwnPropertySymbols(obj));
|
|
1232
1235
|
for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
|
|
1233
1236
|
var key = keys_1[_i];
|
|
1234
1237
|
var value = obj[key];
|
|
1235
1238
|
registrations[key] = value;
|
|
1236
1239
|
}
|
|
1237
|
-
// Invalidates the computed registrations.
|
|
1238
|
-
computedRegistrations = null;
|
|
1239
1240
|
return container;
|
|
1240
1241
|
}
|
|
1241
1242
|
/**
|
|
@@ -1245,6 +1246,22 @@ function createContainer(options, parentContainer) {
|
|
|
1245
1246
|
function inspectCradle() {
|
|
1246
1247
|
return '[AwilixContainer.cradle]';
|
|
1247
1248
|
}
|
|
1249
|
+
/**
|
|
1250
|
+
* Recursively gets a registration by name if it exists in the
|
|
1251
|
+
* current container or any of its' parents.
|
|
1252
|
+
*
|
|
1253
|
+
* @param name {string | symbol} The registration name.
|
|
1254
|
+
*/
|
|
1255
|
+
function getRegistration(name) {
|
|
1256
|
+
var resolver = registrations[name];
|
|
1257
|
+
if (resolver) {
|
|
1258
|
+
return resolver;
|
|
1259
|
+
}
|
|
1260
|
+
if (parentContainer) {
|
|
1261
|
+
return parentContainer.getRegistration(name);
|
|
1262
|
+
}
|
|
1263
|
+
return null;
|
|
1264
|
+
}
|
|
1248
1265
|
/**
|
|
1249
1266
|
* Resolves the registration with the given name.
|
|
1250
1267
|
*
|
|
@@ -1259,13 +1276,9 @@ function createContainer(options, parentContainer) {
|
|
|
1259
1276
|
*/
|
|
1260
1277
|
function resolve(name, resolveOpts) {
|
|
1261
1278
|
resolveOpts = resolveOpts || {};
|
|
1262
|
-
if (!resolutionStack.length) {
|
|
1263
|
-
// Root resolve busts the registration cache.
|
|
1264
|
-
rollUpRegistrations(true);
|
|
1265
|
-
}
|
|
1266
1279
|
try {
|
|
1267
1280
|
// Grab the registration by name.
|
|
1268
|
-
var resolver =
|
|
1281
|
+
var resolver = getRegistration(name);
|
|
1269
1282
|
if (resolutionStack.indexOf(name) > -1) {
|
|
1270
1283
|
throw new AwilixResolutionError(name, resolutionStack, 'Cyclic dependencies detected.');
|
|
1271
1284
|
}
|
|
@@ -1278,20 +1291,20 @@ function createContainer(options, parentContainer) {
|
|
|
1278
1291
|
return createContainer;
|
|
1279
1292
|
}
|
|
1280
1293
|
if (!resolver) {
|
|
1281
|
-
//
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1294
|
+
// Checks for some edge cases.
|
|
1295
|
+
switch (name) {
|
|
1296
|
+
// The following checks ensure that console.log on the cradle does not
|
|
1297
|
+
// throw an error (issue #7).
|
|
1298
|
+
case 'inspect':
|
|
1299
|
+
return inspectCradle;
|
|
1300
|
+
// Edge case: Promise unwrapping will look for a "then" property and attempt to call it.
|
|
1301
|
+
// Return undefined so that we won't cause a resolution error. (issue #109)
|
|
1302
|
+
case 'then':
|
|
1303
|
+
return undefined;
|
|
1304
|
+
// When using `Array.from` or spreading the cradle, this will
|
|
1305
|
+
// return the registration names.
|
|
1306
|
+
case Symbol.iterator:
|
|
1307
|
+
return cradleIterator;
|
|
1295
1308
|
}
|
|
1296
1309
|
if (resolveOpts.allowUnregistered) {
|
|
1297
1310
|
return undefined;
|
|
@@ -1356,8 +1369,8 @@ function createContainer(options, parentContainer) {
|
|
|
1356
1369
|
* @return {boolean}
|
|
1357
1370
|
* Whether or not the registration exists.
|
|
1358
1371
|
*/
|
|
1359
|
-
function
|
|
1360
|
-
return name
|
|
1372
|
+
function hasRegistration(name) {
|
|
1373
|
+
return !!getRegistration(name);
|
|
1361
1374
|
}
|
|
1362
1375
|
/**
|
|
1363
1376
|
* Given a registration, class or function, builds it up and returns it.
|