Socket
Socket
Sign inDemoInstall

scrubbr

Package Overview
Dependencies
67
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.0.1-alpha.7 to 0.0.1-alpha.8

.eslintrc.js

91

dist/Scrubbr.d.ts
import { JSONSchema7 } from 'json-schema';
import { ScrubbrState } from './ScrubbrState';
import { ScrubbrOptions, JSONSchemaDefinitions, TypeSerializer, GenericSerializer } from './types';
import { ScrubbrOptions, JSONSchemaDefinitions, TypeSerializer, GenericSerializer } from '.';
export default class Scrubbr {

@@ -13,10 +12,30 @@ options: ScrubbrOptions;

* Create new scrubbr serializer
* @param {string | JSONSchema7} schema - The TypeScript schema file or JSON object to use for serialization.
* @param {ScrubbrOptions} options - Scrubbr options.
* @param schema - The TypeScript schema file or JSON object to use for serialization.
* @param options - Scrubbr options.
*/
constructor(schema: string | JSONSchemaDefinitions, options?: ScrubbrOptions);
constructor(schema: string | JSONSchemaDefinitions, options: ScrubbrOptions);
/**
* Create new scrubber with the same options and custom serializers
* Create a duplicate version of this scrubbr with all the same serializers, global context, and options.
*
* This is useful to create a global scrubbr with serializer that should be used on all data, and all other
* scrubbrs are created from it for more specific use-cases.
*
* @example
* ```typescript
* // Global config
* const scrubbr = new Scrubbr('./schema.ts');
* scrubbr.addTypeSerializer('User', userSerializer);
*
* // API endpoint
* function commentListApi() {
* const commentScrubbr = scrubbr.clone();
* commentScrubbr.addTypeSerializer('Comment', commentSerializer);
*
* return scrubbr.serialize('CommentList', data);
* }
*
* ```
*
*/
clone(options: ScrubbrOptions): Scrubbr;
clone(options?: ScrubbrOptions): Scrubbr;
/**

@@ -27,9 +46,9 @@ * Replace the schema with a new one

/**
* Return the schema
* Return the entire generated schema for the loaded TypeScript file.
*/
getSchema(): JSONSchema7;
/**
* Return the schema for a TypeScript type.
* @param {string} typeName - The name of the type to return the schema for.
* @return {JSONSchema7 | null} The JSON schema for the type, or null if it was not found.
* Get the the generated JSON schema for a TypeScript type.
* @param typeName - The name of the type to return the schema for.
* @returns The JSON schema for the type, or null if it was not found.
*/

@@ -39,9 +58,9 @@ getSchemaFor(typeName: string): JSONSchema7 | null;

* Add a function to serialize a schema type
* @param {string} typeName - The name of the type to register the serializer for.
* @param {function} serializer - The serializer function.
* @param typeName - One or more type names to register the serializer for.
* @param serializer - The serializer function.
*/
addTypeSerializer(typeName: string, serializer: TypeSerializer): void;
addTypeSerializer(typeName: string | string[], serializer: TypeSerializer): void;
/**
* Add a generic custom serializer function that's called for each node in the object.
* @param {function} serializer - The serializer function.
* @param serializer - The serializer function.
*/

@@ -52,4 +71,5 @@ addGenericSerializer(serializer: GenericSerializer): void;

* You can use this for setting things like the logged-in user, at a global level.
* @param {object} context - Any object you want to set as the context.
* @param {boolean} merge - Automatically merge this context with the existing global context (defaults false)
* @param context - Any object you want to set as the context.
* @param merge - Automatically merge this context with the existing global context (defaults false)
* Otherwise, the global context will be overwritten.
*/

@@ -63,11 +83,20 @@ setGlobalContext(context: object, merge?: boolean): void;

* Serialize data based on a TypeScript type.
* @param {string} schemaType - The name of the typescript type to serialize the data with.
* @param {object} data - The data to serialize
* @param {any} context - Any data you want sent to the custom serializer functions.
*
* You can influence the return type by using the generic angle brackets:
*
* @example
* ```
* scrubbr.serialize<UserList>('UserList', data);
* ```
*
* @param schemaType - The name of the typescript type to serialize the data with.
* @param data - The data to serialize
* @param context - Any data you want sent to the custom serializer functions.
* @param options - Set options for just this serialization.
*/
serialize<Type = any>(schemaType: string, data: object, context?: object): Promise<Type>;
serialize<Type = any>(schemaType: string, data: object, context?: object, options?: ScrubbrOptions): Promise<Type>;
/**
* Traverse into a node of data on an object to serialize.
* @param {object} node: The data object to start from
* @param {ScrubbrState} state - The serializing state.
* @param node: The data object to start from
* @param state - The serializing state.
*/

@@ -77,4 +106,4 @@ private walkData;

* Serialize all the properties of an object.
* @param {object} node - The object to serialize
* @param {ScrubbrState} state - The serializing state.
* @param node - The object to serialize
* @param state - The serializing state.
*/

@@ -84,4 +113,4 @@ private walkObjectNode;

* Serialize all the items of an array.
* @param {any} node[] - The array to serialize
* @param {ScrubbrState} state - The serializing state.
* @param node[] - The array to serialize
* @param state - The serializing state.
*/

@@ -91,4 +120,4 @@ private walkArrayNode;

* Serialize a single piece of data.
* @param {any} data - The data to serialize
* @param {ScrubbrState} state - The serializing state.
* @param data - The data to serialize
* @param state - The serializing state.
*/

@@ -115,7 +144,7 @@ private serializeNode;

*/
isCircularReference(typeName: string, state: ScrubbrState): boolean;
private isCircularReference;
/**
* Handle an error by either throwing an exception or logging it.
*/
error(message: string, state: ScrubbrState): void;
private error;
}

@@ -84,7 +84,6 @@ "use strict";

* Create new scrubbr serializer
* @param {string | JSONSchema7} schema - The TypeScript schema file or JSON object to use for serialization.
* @param {ScrubbrOptions} options - Scrubbr options.
* @param schema - The TypeScript schema file or JSON object to use for serialization.
* @param options - Scrubbr options.
*/
function Scrubbr(schema, options) {
if (options === void 0) { options = {}; }
this.schema = {};

@@ -94,3 +93,3 @@ this.typeSerializers = new Map();

this.globalContext = {};
this.options = __assign(__assign({}, defaultOptions), options);
this.options = __assign(__assign({}, defaultOptions), (options || {}));
this.logger = new Logger_1.Logger(options);

@@ -100,6 +99,30 @@ this.loadSchema(schema);

/**
* Create new scrubber with the same options and custom serializers
* Create a duplicate version of this scrubbr with all the same serializers, global context, and options.
*
* This is useful to create a global scrubbr with serializer that should be used on all data, and all other
* scrubbrs are created from it for more specific use-cases.
*
* @example
* ```typescript
* // Global config
* const scrubbr = new Scrubbr('./schema.ts');
* scrubbr.addTypeSerializer('User', userSerializer);
*
* // API endpoint
* function commentListApi() {
* const commentScrubbr = scrubbr.clone();
* commentScrubbr.addTypeSerializer('Comment', commentSerializer);
*
* return scrubbr.serialize('CommentList', data);
* }
*
* ```
*
*/
Scrubbr.prototype.clone = function (options) {
if (!options) {
options = this.options;
}
var cloned = new Scrubbr(this.schema, options);
cloned.setGlobalContext(this.globalContext);
this.genericSerializers.forEach(function (serializerFn) {

@@ -139,3 +162,3 @@ cloned.addGenericSerializer(serializerFn);

/**
* Return the schema
* Return the entire generated schema for the loaded TypeScript file.
*/

@@ -146,5 +169,5 @@ Scrubbr.prototype.getSchema = function () {

/**
* Return the schema for a TypeScript type.
* @param {string} typeName - The name of the type to return the schema for.
* @return {JSONSchema7 | null} The JSON schema for the type, or null if it was not found.
* Get the the generated JSON schema for a TypeScript type.
* @param typeName - The name of the type to return the schema for.
* @returns The JSON schema for the type, or null if it was not found.
*/

@@ -161,15 +184,21 @@ Scrubbr.prototype.getSchemaFor = function (typeName) {

* Add a function to serialize a schema type
* @param {string} typeName - The name of the type to register the serializer for.
* @param {function} serializer - The serializer function.
* @param typeName - One or more type names to register the serializer for.
* @param serializer - The serializer function.
*/
Scrubbr.prototype.addTypeSerializer = function (typeName, serializer) {
var serializerList = this.typeSerializers.get(typeName) || [];
serializerList.push(serializer);
this.typeSerializers.set(typeName, serializerList);
var _this = this;
var typeNames = (Array.isArray(typeName)) ? typeName : [typeName];
typeNames.forEach(function (name) {
_this.logger.debug("Adding custom serializer for type: " + name);
var serializerList = _this.typeSerializers.get(name) || [];
serializerList.push(serializer);
_this.typeSerializers.set(name, serializerList);
});
};
/**
* Add a generic custom serializer function that's called for each node in the object.
* @param {function} serializer - The serializer function.
* @param serializer - The serializer function.
*/
Scrubbr.prototype.addGenericSerializer = function (serializer) {
this.logger.debug("Adding generic serializer");
this.genericSerializers.push(serializer);

@@ -180,4 +209,5 @@ };

* You can use this for setting things like the logged-in user, at a global level.
* @param {object} context - Any object you want to set as the context.
* @param {boolean} merge - Automatically merge this context with the existing global context (defaults false)
* @param context - Any object you want to set as the context.
* @param merge - Automatically merge this context with the existing global context (defaults false)
* Otherwise, the global context will be overwritten.
*/

@@ -201,18 +231,31 @@ Scrubbr.prototype.setGlobalContext = function (context, merge) {

* Serialize data based on a TypeScript type.
* @param {string} schemaType - The name of the typescript type to serialize the data with.
* @param {object} data - The data to serialize
* @param {any} context - Any data you want sent to the custom serializer functions.
*
* You can influence the return type by using the generic angle brackets:
*
* @example
* ```
* scrubbr.serialize<UserList>('UserList', data);
* ```
*
* @param schemaType - The name of the typescript type to serialize the data with.
* @param data - The data to serialize
* @param context - Any data you want sent to the custom serializer functions.
* @param options - Set options for just this serialization.
*/
Scrubbr.prototype.serialize = function (schemaType, data, context) {
Scrubbr.prototype.serialize = function (schemaType, data, context, options) {
if (context === void 0) { context = {}; }
if (options === void 0) { options = {}; }
return __awaiter(this, void 0, void 0, function () {
var schema, cloned, state, serialized;
var schema, state, cloned, serialized;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
this.logger.info("Serializing data with TS type: '" + schemaType + "'");
schema = this.getSchemaFor(schemaType);
if (!schema) {
throw new Error("Could not find the type: " + schemaType);
throw this.error("Could not find the type: " + schemaType);
}
this.logger.info("Serializing data with TS type: '" + schemaType + "'");
// Create state
options = __assign(__assign({}, this.options), options);
state = new ScrubbrState_1.ScrubbrState(data, schema, options, context);
cloned = JSON.parse(JSON.stringify(data));

@@ -222,3 +265,3 @@ // Merge contexts

this.logger.debug("Using context: '" + JSON.stringify(context, null, ' ') + "'");
state = new ScrubbrState_1.ScrubbrState(data, schema, this.options, context);
// Serialize
state.rootSchemaType = schemaType;

@@ -236,4 +279,4 @@ state.schemaType = schemaType;

* Traverse into a node of data on an object to serialize.
* @param {object} node: The data object to start from
* @param {ScrubbrState} state - The serializing state.
* @param node: The data object to start from
* @param state - The serializing state.
*/

@@ -265,4 +308,4 @@ Scrubbr.prototype.walkData = function (node, state) {

* Serialize all the properties of an object.
* @param {object} node - The object to serialize
* @param {ScrubbrState} state - The serializing state.
* @param node - The object to serialize
* @param state - The serializing state.
*/

@@ -309,4 +352,4 @@ Scrubbr.prototype.walkObjectNode = function (node, state) {

* Serialize all the items of an array.
* @param {any} node[] - The array to serialize
* @param {ScrubbrState} state - The serializing state.
* @param node[] - The array to serialize
* @param state - The serializing state.
*/

@@ -357,4 +400,4 @@ Scrubbr.prototype.walkArrayNode = function (node, state) {

* Serialize a single piece of data.
* @param {any} data - The data to serialize
* @param {ScrubbrState} state - The serializing state.
* @param data - The data to serialize
* @param state - The serializing state.
*/

@@ -505,2 +548,5 @@ Scrubbr.prototype.serializeNode = function (data, state) {

state.logger.debug("Overriding type: '" + serialized.typeName + "'");
if (serialized.typeName === state.schemaType) {
state.logger.warn("Trying to override type with the same type ('" + serialized.typeName + "') at object path: " + state.path);
}
state = _this.setStateSchemaDefinition(serialized.typeName, state);

@@ -540,21 +586,25 @@ return data;

case 1:
if (!(i < serializerFns.length)) return [3 /*break*/, 6];
if (!(i < serializerFns.length)) return [3 /*break*/, 7];
return [4 /*yield*/, serializerFns[i].call(null, dataNode, state)];
case 2:
serialized = _a.sent();
if (!(serialized instanceof helpers_1.UseType && serialized.typeName !== typeName)) return [3 /*break*/, 4];
if (!(serialized instanceof helpers_1.UseType && serialized.typeName !== typeName)) return [3 /*break*/, 5];
typeName_1 = serialized.typeName;
state.logger.debug("Overriding type: '" + typeName_1 + "'");
if (!(serialized.typeName === state.schemaType)) return [3 /*break*/, 3];
state.logger.warn("Trying to override type with the same type ('" + serialized.typeName + "') at object path: " + state.path);
return [3 /*break*/, 5];
case 3:
circularRef = this.isCircularReference(typeName_1, state);
if (!!circularRef) return [3 /*break*/, 4];
if (!!circularRef) return [3 /*break*/, 5];
state = this.setStateSchemaDefinition(typeName_1, state);
return [4 /*yield*/, this.runTypeSerializers(dataNode, state)];
case 3: return [2 /*return*/, _a.sent()];
case 4:
case 4: return [2 /*return*/, _a.sent()];
case 5:
dataNode = serialized;
_a.label = 5;
case 5:
_a.label = 6;
case 6:
i++;
return [3 /*break*/, 1];
case 6: return [2 /*return*/, dataNode];
case 7: return [2 /*return*/, dataNode];
}

@@ -578,6 +628,11 @@ });

Scrubbr.prototype.error = function (message, state) {
if (this.options.throwOnError) {
var _a;
var throwOnError = (state) ? (_a = state === null || state === void 0 ? void 0 : state.options) === null || _a === void 0 ? void 0 : _a.throwOnError : this.options.throwOnError;
if (throwOnError) {
throw new Error(message);
}
state.logger.error(message);
if (state) {
state.logger.error(message);
}
this.logger.error(message);
};

@@ -584,0 +639,0 @@ return Scrubbr;

@@ -38,7 +38,7 @@ import { JSONSchema7 } from 'json-schema';

/**
* The context object passed in to the serialize function.
* The context object passed to the serialize function.
*/
context: any;
/**
* The nesting level at this node of the data being serialized
* The nesting level at this node of the data being serialized.
*/

@@ -45,0 +45,0 @@ nesting: number;

@@ -34,7 +34,7 @@ "use strict";

/**
* The context object passed in to the serialize function.
* The context object passed to the serialize function.
*/
this.context = {};
/**
* The nesting level at this node of the data being serialized
* The nesting level at this node of the data being serialized.
*/

@@ -41,0 +41,0 @@ this.nesting = 0;

@@ -83,6 +83,9 @@ # Scrubbr

## That's it
## Next up
Follow along for more advanced features.
Learn about [Custom Serializers](serializers.md) next.
- [Custom Serializers](serializers.md)
- [Tips & Tricks](tips.md)
- [Troubleshooting](troubleshooting.md)
- [API Docs](api/scrubbr.md)

@@ -44,2 +44,26 @@ # Tips & Tricks

## Clone the scrubbr serializer
For performance reasons you might not want all the custom serializers for your entire app running on every object serialized. You also probably don't want to manually add the global serializers every time.
You can use `clone()` to create API-specific scrubbrs off the global version. The TypeScript schema, scrubbr options, and custome serializers will be included in the cloned version.
In this example we want the `userSerializer` used all data serialized and the `commentSerializer` only applied to the comment list API:
```typescript
// Global config
const scrubbr = new Scrubbr('./schema.ts');
scrubbr.addTypeSerializer('User', userSerializer);
// API endpoint
function commentListApi() {
const commentScrubbr = scrubbr.clone();
commentScrubbr.addTypeSerializer('Comment', commentSerializer);
return scrubbr.serialize('CommentList', data);
}
```
## Schema Validation

@@ -46,0 +70,0 @@

@@ -10,8 +10,6 @@ # Troubleshooting

```
This is the [JSON schema](https://json-schema.org/understanding-json-schema/) that was created from your TypeScript file.
!!! NOTE
This is the [JSON schema](https://json-schema.org/understanding-json-schema/) that was created from your TypeScript file.
Next look at the schema definition for the type you're trying to serialize to.
Next look at the schema definition for the TypeScript type you're trying to serialize to.
```typescript

@@ -18,0 +16,0 @@ console.log(scrubbr.getSchemaFor('UserList'));

{
"name": "scrubbr",
"version": "0.0.1-alpha.7",
"version": "0.0.1-alpha.8",
"description": "Serialize and sanitize JSON data using TypeScript.",

@@ -9,7 +9,9 @@ "repository": "https://github.com/jgillick/scrubbr",

"prepare": "npm run build",
"build": "rm -rf ./dist && tsc",
"clean": "rm -rf ./dist docs/api/*",
"build": "npm run clean && tsc",
"test": "jest",
"example": "ts-node ./example/index.ts",
"docs": "mkdocs serve",
"docs:build": "mkdocs build"
"docs": "npm run docs:api && mkdocs serve",
"docs:build": "npm run docs:api && mkdocs build",
"docs:api": "npm run build && (api-extractor run || true) && api-documenter markdown -i ./temp -o docs/api"
},

@@ -23,3 +25,9 @@ "author": "Jeremy Gillick",

"devDependencies": {
"@microsoft/api-documenter": "^7.13.24",
"@microsoft/api-extractor": "^7.16.1",
"@types/jest": "^26.0.23",
"@typescript-eslint/eslint-plugin": "^4.28.0",
"@typescript-eslint/parser": "^4.28.0",
"eslint": "^7.29.0",
"eslint-plugin-tsdoc": "^0.2.14",
"jest": "^27.0.4",

@@ -26,0 +34,0 @@ "moment": "^2.29.1",

@@ -5,3 +5,3 @@ # Scrubbr

[![npm version](https://img.shields.io/npm/v/scrubbr)](https://badge.fury.io/js/scrubbr)
[![downloads](https://img.shields.io/npm/dm/Scrubbr)](https://www.npmjs.com/package/scrubbr)
[![downloads](https://img.shields.io/npm/dm/scrubbr)](https://www.npmjs.com/package/scrubbr)

@@ -14,3 +14,3 @@ Serialize JSON data using TypeScript.

[Documentation](https://jgillick.github.io/scrubbr/)
[Documentation](https://jgillick.github.io/scrubbr/) | [API](https://jgillick.github.io/scrubbr/api/scrubbr/)

@@ -17,0 +17,0 @@ ## Install

@@ -13,3 +13,3 @@ import * as fs from 'fs';

GenericSerializer,
} from './types';
} from '.';

@@ -35,12 +35,12 @@ const defaultOptions = {

* Create new scrubbr serializer
* @param {string | JSONSchema7} schema - The TypeScript schema file or JSON object to use for serialization.
* @param {ScrubbrOptions} options - Scrubbr options.
* @param schema - The TypeScript schema file or JSON object to use for serialization.
* @param options - Scrubbr options.
*/
constructor(
schema: string | JSONSchemaDefinitions,
options: ScrubbrOptions = {}
options: ScrubbrOptions
) {
this.options = {
...defaultOptions,
...options,
...(options || {}),
};

@@ -52,6 +52,30 @@ this.logger = new Logger(options);

/**
* Create new scrubber with the same options and custom serializers
* Create a duplicate version of this scrubbr with all the same serializers, global context, and options.
*
* This is useful to create a global scrubbr with serializer that should be used on all data, and all other
* scrubbrs are created from it for more specific use-cases.
*
* @example
* ```typescript
* // Global config
* const scrubbr = new Scrubbr('./schema.ts');
* scrubbr.addTypeSerializer('User', userSerializer);
*
* // API endpoint
* function commentListApi() {
* const commentScrubbr = scrubbr.clone();
* commentScrubbr.addTypeSerializer('Comment', commentSerializer);
*
* return scrubbr.serialize('CommentList', data);
* }
*
* ```
*
*/
clone(options: ScrubbrOptions): Scrubbr {
clone(options?: ScrubbrOptions): Scrubbr {
if (!options) {
options = this.options;
}
const cloned = new Scrubbr(this.schema as JSONSchemaDefinitions, options);
cloned.setGlobalContext(this.globalContext);

@@ -100,3 +124,3 @@ this.genericSerializers.forEach((serializerFn) => {

/**
* Return the schema
* Return the entire generated schema for the loaded TypeScript file.
*/

@@ -108,5 +132,5 @@ getSchema(): JSONSchema7 {

/**
* Return the schema for a TypeScript type.
* @param {string} typeName - The name of the type to return the schema for.
* @return {JSONSchema7 | null} The JSON schema for the type, or null if it was not found.
* Get the the generated JSON schema for a TypeScript type.
* @param typeName - The name of the type to return the schema for.
* @returns The JSON schema for the type, or null if it was not found.
*/

@@ -123,9 +147,13 @@ getSchemaFor(typeName: string): JSONSchema7 | null {

* Add a function to serialize a schema type
* @param {string} typeName - The name of the type to register the serializer for.
* @param {function} serializer - The serializer function.
* @param typeName - One or more type names to register the serializer for.
* @param serializer - The serializer function.
*/
addTypeSerializer(typeName: string, serializer: TypeSerializer) {
const serializerList = this.typeSerializers.get(typeName) || [];
serializerList.push(serializer);
this.typeSerializers.set(typeName, serializerList);
addTypeSerializer(typeName: string | string[], serializer: TypeSerializer) {
const typeNames = (Array.isArray(typeName)) ? typeName : [typeName];
typeNames.forEach((name) => {
this.logger.debug(`Adding custom serializer for type: ${name}`);
const serializerList = this.typeSerializers.get(name) || [];
serializerList.push(serializer);
this.typeSerializers.set(name, serializerList);
});
}

@@ -135,5 +163,6 @@

* Add a generic custom serializer function that's called for each node in the object.
* @param {function} serializer - The serializer function.
* @param serializer - The serializer function.
*/
addGenericSerializer(serializer: GenericSerializer) {
this.logger.debug(`Adding generic serializer`);
this.genericSerializers.push(serializer);

@@ -145,4 +174,5 @@ }

* You can use this for setting things like the logged-in user, at a global level.
* @param {object} context - Any object you want to set as the context.
* @param {boolean} merge - Automatically merge this context with the existing global context (defaults false)
* @param context - Any object you want to set as the context.
* @param merge - Automatically merge this context with the existing global context (defaults false)
* Otherwise, the global context will be overwritten.
*/

@@ -169,5 +199,14 @@ setGlobalContext(context: object, merge: boolean = false) {

* Serialize data based on a TypeScript type.
* @param {string} schemaType - The name of the typescript type to serialize the data with.
* @param {object} data - The data to serialize
* @param {any} context - Any data you want sent to the custom serializer functions.
*
* You can influence the return type by using the generic angle brackets:
*
* @example
* ```
* scrubbr.serialize<UserList>('UserList', data);
* ```
*
* @param schemaType - The name of the typescript type to serialize the data with.
* @param data - The data to serialize
* @param context - Any data you want sent to the custom serializer functions.
* @param options - Set options for just this serialization.
*/

@@ -177,11 +216,23 @@ async serialize<Type = any>(

data: object,
context: object = {}
context: object = {},
options: ScrubbrOptions = {}
): Promise<Type> {
this.logger.info(`Serializing data with TS type: '${schemaType}'`);
const schema = this.getSchemaFor(schemaType);
if (!schema) {
throw new Error(`Could not find the type: ${schemaType}`);
throw this.error(`Could not find the type: ${schemaType}`);
}
this.logger.info(`Serializing data with TS type: '${schemaType}'`);
// Create state
options = {
...this.options,
...options,
};
const state: ScrubbrState = new ScrubbrState(
data,
schema,
options,
context
);
// Validate JSON and clone

@@ -198,8 +249,2 @@ const cloned = JSON.parse(JSON.stringify(data));

// Serialize
const state: ScrubbrState = new ScrubbrState(
data,
schema,
this.options,
context
);
state.rootSchemaType = schemaType;

@@ -213,4 +258,4 @@ state.schemaType = schemaType;

* Traverse into a node of data on an object to serialize.
* @param {object} node: The data object to start from
* @param {ScrubbrState} state - The serializing state.
* @param node: The data object to start from
* @param state - The serializing state.
*/

@@ -232,4 +277,4 @@ private async walkData(node: Object, state: ScrubbrState): Promise<Object> {

* Serialize all the properties of an object.
* @param {object} node - The object to serialize
* @param {ScrubbrState} state - The serializing state.
* @param node - The object to serialize
* @param state - The serializing state.
*/

@@ -268,4 +313,4 @@ private async walkObjectNode(

* Serialize all the items of an array.
* @param {any} node[] - The array to serialize
* @param {ScrubbrState} state - The serializing state.
* @param node[] - The array to serialize
* @param state - The serializing state.
*/

@@ -310,4 +355,4 @@ private async walkArrayNode(node: any[], state: ScrubbrState): Promise<any> {

* Serialize a single piece of data.
* @param {any} data - The data to serialize
* @param {ScrubbrState} state - The serializing state.
* @param data - The data to serialize
* @param state - The serializing state.
*/

@@ -477,2 +522,6 @@ private async serializeNode(data: any, state: ScrubbrState): Promise<Object> {

state.logger.debug(`Overriding type: '${serialized.typeName}'`);
if (serialized.typeName === state.schemaType) {
state.logger.warn(`Trying to override type with the same type ('${serialized.typeName}') at object path: ${state.path}`);
}
state = this.setStateSchemaDefinition(serialized.typeName, state);

@@ -520,7 +569,11 @@ return data;

// Check for circular reference
const circularRef = this.isCircularReference(typeName, state);
if (!circularRef) {
state = this.setStateSchemaDefinition(typeName, state);
return await this.runTypeSerializers(dataNode, state);
if (serialized.typeName === state.schemaType) {
state.logger.warn(`Trying to override type with the same type ('${serialized.typeName}') at object path: ${state.path}`);
} else {
// Check for circular reference
const circularRef = this.isCircularReference(typeName, state);
if (!circularRef) {
state = this.setStateSchemaDefinition(typeName, state);
return await this.runTypeSerializers(dataNode, state);
}
}

@@ -537,3 +590,3 @@ }

*/
isCircularReference(typeName: string, state: ScrubbrState): boolean {
private isCircularReference(typeName: string, state: ScrubbrState): boolean {
if (state.seenTypes.includes(typeName)) {

@@ -552,8 +605,12 @@ this.error(

*/
error(message: string, state: ScrubbrState) {
if (this.options.throwOnError) {
private error(message: string, state?: ScrubbrState) {
const throwOnError = (state) ? state?.options?.throwOnError : this.options.throwOnError;
if (throwOnError) {
throw new Error(message);
}
state.logger.error(message);
if (state) {
state.logger.error(message);
}
this.logger.error(message);
}
}

@@ -47,3 +47,3 @@ import { JSONSchema7 } from 'json-schema';

/**
* The context object passed in to the serialize function.
* The context object passed to the serialize function.
*/

@@ -53,3 +53,3 @@ context: any = {};

/**
* The nesting level at this node of the data being serialized
* The nesting level at this node of the data being serialized.
*/

@@ -56,0 +56,0 @@ nesting: number = 0;

@@ -59,2 +59,25 @@ import 'jest';

});
test('add multiple types to a single serializer', async () => {
let receivedTypes = new Set<string>();
const serializerFn = jest.fn((data, state) => {
receivedTypes.add(state.schemaType);
return data;
});
const data = {
node: {
id: 'bar',
value: 'boo',
},
other: { value: 'foo' },
};
scrubbr.addTypeSerializer(['TargetTypeA', 'TargetTypeB'], serializerFn);
await scrubbr.serialize('TypeSerializerTest', data, {});
expect(serializerFn).toHaveBeenCalledTimes(2);
expect(Array.from(receivedTypes)).toEqual(['TargetTypeA', 'TargetTypeB']);
})
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc