@muffin-dev/exposer
v1.2.0
Published
This module allows you use property decorators on an object to define which of its properties are exposed, and so you can retrieve it using expose() method.
Downloads
6
Readme
Muffin Dev for Node - Exposer
This module allows you to mark object properties or accessors "exposable", and so make a new object that contains only the exposed properties.
Installation
Install it with npm:
npm i @muffin-dev/exposer
Usage
A common use case for exposing properties when making a web API is to expose only public properties of an entity (e.g. User) when sending the data to the client.
The following examples will show you how to setup an exposed class and its properties for the User entity scenario with different languages.
Using vanilla JS
const { expose, markExposed } = require('@muffin-dev/exposer');
class User {
username = 'RandomUser';
password = 'S3cr3t!';
email = '[email protected]';
}
// Mark the username and email properties exposables
markExposed(User, 'username');
markExposed(User, 'email');
// Outputs { username: "RandomUser", email: "[email protected]" }
console.log(expose(new User()));
You can do the same by making all a class properties exposables, and then ignoring only the properties you don't want to be exposed with markExcluded()
:
const { expose, markExposed, markExcluded } = require('@muffin-dev/exposer');
class User {
username = 'RandomUser';
password = 'S3cr3t!';
email = '[email protected]';
}
// Mark the entire User class exposed, so all its properties are also exposed
markExposed(User);
// Then, exclude the password property
markExcluded(User, 'password');
// Outputs { username: "RandomUser", email: "[email protected]" }
console.log(expose(new User()));
Using TypeScript
import { expose, markExposed, markExcluded } from '@muffin-dev/exposer';
class User {
username = 'RandomUser';
password = 'S3cr3t!';
email = '[email protected]';
}
// Mark the entire User class exposed, so all its properties are also exposed
markExposed(User);
// Then, exclude the password property
markExcluded(User, 'password');
// Outputs { username: "RandomUser", email: "[email protected]" }
console.log(expose(new User()));
Using TypeScript decorators
The decorators are still an experimental feature of TypeScript that you need to enable in your tsconfig.json
file:
{
"compilerOptions": {
"experimentalDecorators": true
}
}
import { expose, Expose, Exclude } from '@muffin-dev/exposer';
// Mark the entire User class exposed, so all its properties are also exposed
@Expose()
class User {
username = 'RandomUser';
// Then, exclude the password property
@Exclude()
password = 'S3cr3t!';
email = '[email protected]';
}
// Outputs { username: "RandomUser", email: "[email protected]" }
console.log(expose(new User()));
Advanced usage: groups
You can also setup "groups" on your exposed classes and properties, which allow to filter the exposed properties.
Using vanilla JavaScript
const { expose, markExposed, markExcluded } = require('@muffin-dev/exposer');
class User {
username = 'RandomUser';
password = 'S3cr3t!';
email = '[email protected]';
_privateProperty = { };
}
// Mark the entire class exposed
markExposed(User);
// Exclude password property first
markExcluded(User, 'password');
// Then expose it only for the "private" group
markExposed(User, 'password', 'private');
// Exclude _privateProperty for any group
markExcluded(User, '_privateProperty');
// Outputs { username: "RandomUser", email: "[email protected]" }
console.log(expose(new User()));
// Outputs { username: "RandomUser", password: "S3cr3t!", email: "[email protected]" }
console.log(expose(new User(), 'private'));
Using TypeScript
import { expose, markExposed, markExcluded } from '@muffin-dev/exposer';
class User {
username = 'RandomUser';
password = 'S3cr3t!';
email = '[email protected]';
_privateProperty = { };
}
// Mark the entire class exposed
markExposed(User);
// Exclude password property first
markExcluded(User, 'password');
// Then expose it only for the "private" group
markExposed(User, 'password', 'private');
// Exclude _privateProperty for any group
markExcluded(User, '_privateProperty');
// Outputs { username: "RandomUser", email: "[email protected]" }
console.log(expose(new User()));
// Outputs { username: "RandomUser", password: "S3cr3t!", email: "[email protected]" }
console.log(expose(new User(), 'private'));
Using TypeScript decorators
import { expose, Expose, Exclude } from '@muffin-dev/exposer';
// Mark the entire class exposed
@Expose()
class User {
username = 'RandomUser';
// Exclude password property first, then expose it only for the "private" group
@Exclude() @Expose('private')
password = 'S3cr3t!';
email = '[email protected]';
// Exclude _privateProperty for any group
@Exclude()
_privateProperty = { };
}
// Outputs { username: "RandomUser", email: "[email protected]" }
console.log(expose(new User()));
// Outputs { username: "RandomUser", password: "S3cr3t!", email: "[email protected]" }
console.log(expose(new User(), 'private'));
API documentation
Methods
markExposed()
function markExposed(
objectClass: TConstructor | string | Record <string, unknown>,
propertyName: string = null,
groups: string | string[] = null
): void
Marks a class or a property "exposed".
objectClass: TConstructor | string | Record <string, unknown>
: A constructor method, an instance or the name of the class on which the operation will be performedpropertyName: string = null
: The name of the property on which to apply the operation. Null if the operation applies to a classgroups: string | string[] = null
: The eventual group(s) that the class or the property should be exposed for. If null given, the class or the property is exposed to any group
markExcluded()
function markExcluded(objectClass: TConstructor | string | Record <string, unknown>, propertyName: string): void
Marks a property "excluded", so it won't be exposed to any group.
objectClass: TConstructor | string | Record <string, unknown>
: A constructor method, an instance or the name of the class on which the operation will be performedpropertyName: string
: The name of the property on which to apply the operation
expose()
function expose<TObject = Record<string, unknown>>(instance: TObject, groups?: string | string[]): Partial<TObject>;
function expose<TObject = Record<string, unknown>>(className: string, obj: TObject | Record<string, unknown>, groups?: string | string[]): Partial<TObject>;
function expose<TObject = Record<string, unknown>>(
objectClass: new () => TObject | TObject,
obj: TObject | Record<string, unknown>,
groups?: string | string[]
): Partial<TObject>
Makes a new object that contains only the exposed properties.
- template
TObject
: The type of the input object. instance: TObject
: An instance of the class you want to exposeclassName: string
: The class name of the object you want to exposeobjectClass
: The constructor method or an instance of the class you want to exposeobj
: The object that contains the data to exposegroups
: If given, only the properties exposed for the named groups will be set on the output object
Returns a new object with the exposed properties.
Decorators
@Expose()
@Expose(groups: string|string[] = null)
Marks a class or a property as exposed.
group: string | string[]
: The eventual group(s) you want that class or property to be exposed for. If null or empty array given, the class or the property is exposed to every groups
@Exclude()
Exclude()
Marks a property "excluded", so it won't be exposed to any group.
You can use this decorator before using the @Expose()
decorator in order to make a property "excluded but for these groups" in an exposed class:
@Expose()
class MyClass {
public exposedForAllGroups;
@Exclude() @Expose('demo')
public exposedOnlyForDemoGroup;
}
Future improvements
- Add an option for
expose()
to returnnull
instead of an any object if no exposed properties are found