@poppinss/utils
Advanced tools
Comparing version 2.5.9 to 2.5.10
export { base64 } from './src/base64'; | ||
export { compose, NormalizeConstructor } from './src/compose'; | ||
export * as lodash from './src/lodash'; | ||
@@ -3,0 +4,0 @@ export { Exception } from './src/Exception'; |
@@ -30,5 +30,7 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ManagerConfigValidator = exports.defineStaticProperty = exports.MessageBuilder = exports.randomString = exports.resolveFrom = exports.esmResolver = exports.interpolate = exports.esmRequire = exports.requireAll = exports.resolveDir = exports.fsReadAll = exports.safeStringify = exports.safeParse = exports.safeEqual = exports.Exception = exports.lodash = exports.base64 = void 0; | ||
exports.ManagerConfigValidator = exports.defineStaticProperty = exports.MessageBuilder = exports.randomString = exports.resolveFrom = exports.esmResolver = exports.interpolate = exports.esmRequire = exports.requireAll = exports.resolveDir = exports.fsReadAll = exports.safeStringify = exports.safeParse = exports.safeEqual = exports.Exception = exports.lodash = exports.compose = exports.base64 = void 0; | ||
var base64_1 = require("./src/base64"); | ||
Object.defineProperty(exports, "base64", { enumerable: true, get: function () { return base64_1.base64; } }); | ||
var compose_1 = require("./src/compose"); | ||
Object.defineProperty(exports, "compose", { enumerable: true, get: function () { return compose_1.compose; } }); | ||
// @ts-ignore | ||
@@ -35,0 +37,0 @@ exports.lodash = __importStar(require("./src/lodash")); |
{ | ||
"name": "@poppinss/utils", | ||
"version": "2.5.9", | ||
"version": "2.5.10", | ||
"description": "Handy utilities for repetitive work", | ||
@@ -34,23 +34,23 @@ "main": "build/index.js", | ||
"@adonisjs/mrm-preset": "^2.4.0", | ||
"@adonisjs/require-ts": "^1.1.0", | ||
"@adonisjs/require-ts": "^1.1.1", | ||
"@poppinss/dev-utils": "^1.0.11", | ||
"@types/ms": "^0.7.31", | ||
"@types/node": "^14.14.8", | ||
"commitizen": "^4.2.2", | ||
"@types/node": "^14.14.22", | ||
"commitizen": "^4.2.3", | ||
"cz-conventional-changelog": "^3.3.0", | ||
"del-cli": "^3.0.1", | ||
"doctoc": "^1.4.0", | ||
"eslint": "^7.13.0", | ||
"eslint-config-prettier": "^6.15.0", | ||
"doctoc": "^2.0.0", | ||
"eslint": "^7.18.0", | ||
"eslint-config-prettier": "^7.2.0", | ||
"eslint-plugin-adonis": "^1.0.15", | ||
"eslint-plugin-prettier": "^3.1.4", | ||
"eslint-plugin-prettier": "^3.3.1", | ||
"github-label-sync": "^2.0.0", | ||
"husky": "^4.3.0", | ||
"husky": "^4.3.8", | ||
"japa": "^3.1.1", | ||
"lodash-cli": "^4.17.5", | ||
"mrm": "^2.5.12", | ||
"np": "^7.0.0", | ||
"mrm": "^2.5.13", | ||
"np": "^7.2.0", | ||
"npm-audit-html": "^1.5.0", | ||
"prettier": "^2.1.2", | ||
"typescript": "^4.0.5" | ||
"prettier": "^2.2.1", | ||
"typescript": "^4.1.3" | ||
}, | ||
@@ -85,3 +85,3 @@ "nyc": { | ||
"klona": "^2.0.4", | ||
"ms": "^2.1.2", | ||
"ms": "^2.1.3", | ||
"require-all": "^3.0.0", | ||
@@ -88,0 +88,0 @@ "resolve-from": "^5.0.0" |
@@ -37,2 +37,4 @@ <div align="center"><img src="https://res.cloudinary.com/adonisjs/image/upload/q_100/v1557762307/poppinss_iftxlt.jpg" width="600px"></div> | ||
- [defineStaticProperty](#definestaticproperty) | ||
- [compose](#compose) | ||
- [Mixins gotchas](#mixins-gotchas) | ||
@@ -348,2 +350,3 @@ <!-- END doctoc generated TOC please keep comment here to allow auto update --> | ||
## defineStaticProperty | ||
Explicitly define static properties on a class by checking for `hasOwnProperty`. In case of inheritance, the properties from the parent class are cloned vs following the prototypal inheritance. | ||
@@ -401,2 +404,82 @@ | ||
## compose | ||
Javascript doesn't have a concept of inherting multiple classes together and neither does Typescript. However, the [official documentation](https://www.typescriptlang.org/docs/handbook/mixins.html) of Typescript does talks about the concept of mixins. | ||
As per the Typescript docs, you can create and apply mixins as follows. | ||
```ts | ||
type Constructor = new (...args: any[]) => any | ||
const UserWithEmail = <T extends Constructor>(superclass: T) => { | ||
return class extends superclass { | ||
public email: string | ||
} | ||
} | ||
const UserWithPassword = <T extends Constructor>(superclass: T) => { | ||
return class extends superclass { | ||
public password: string | ||
} | ||
} | ||
class BaseModel {} | ||
class User extends UserWithPassword(UserWithEmail(BaseModel)) {} | ||
``` | ||
Mixins are close to perfect way of inherting multiple classes. I recommend reading [this article](https://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/) for same. | ||
However, the syntax of applying multiple mixins is kind of ugly, as you have apply mixins over mixins creating a nested hierarchy as shown below. | ||
```ts | ||
UserWithAttributes(UserWithAge(UserWithPassword(UserWithEmail(BaseModel)))) | ||
``` | ||
The `compose` method is a small utility to improve the syntax a bit. | ||
```ts | ||
import { compose } from '@poppinss/utils' | ||
class User extends compose( | ||
BaseModel, | ||
UserWithPassword, | ||
UserWithEmail, | ||
UserWithAge, | ||
UserWithAttributes | ||
) {} | ||
``` | ||
### Mixins gotchas | ||
Typescript has an [open issue](https://github.com/microsoft/TypeScript/issues/37142) related to the constructor arguments of the mixin class or the base class. | ||
Typescript expects all classes used in the mixin chain to have a constructor with only one argument of `...args: any[]`. For example: The following code will work fine at runtime, but the **typescript compiler complains about it**. | ||
```ts | ||
class BaseModel { | ||
constructor(name: string) {} | ||
} | ||
const UserWithEmail = <T extends typeof BaseModel>(superclass: T) => { | ||
return class extends superclass { | ||
// ERROR: A mixin class must have a constructor with a single rest parameter of type 'any[]'.ts(2545) | ||
public email: string | ||
} | ||
} | ||
class User extends compose(BaseModel, UserWithEmail) {} | ||
``` | ||
You can work around this by overriding the constructor of the base class. | ||
```ts | ||
import { NormalizeConstructor, compose } from '@poppinss/utils' | ||
const UserWithEmail = <T extends NormalizeConstructor<typeof BaseModel>>(superclass: T) => { | ||
return class extends superclass { | ||
public email: string | ||
} | ||
} | ||
``` | ||
[circleci-image]: https://img.shields.io/circleci/project/github/poppinss/utils/master.svg?style=for-the-badge&logo=circleci | ||
@@ -403,0 +486,0 @@ [circleci-url]: https://circleci.com/gh/poppinss/utils 'circleci' |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
79008
42
1119
492
Updatedms@^2.1.3