Join our webinar on Wednesday, June 26, at 1pm EDTHow Chia Mitigates Risk in the Crypto Industry.Register
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.9 to 0.0.1-alpha.10

7

dist/helpers.d.ts

@@ -11,8 +11,11 @@ /**

*
* @param typeName - The type that this node should be serialized with.
* @param serializedData - Serialized/transformed data for this node.
* @public
*/
export declare function useType(typeName: string): UseType;
export declare function useType(typeName: string, serializedData?: unknown): UseType;
export declare class UseType {
typeName: string;
constructor(typeName: string);
data: unknown;
constructor(typeName: string, data?: unknown);
}

@@ -14,11 +14,14 @@ "use strict";

*
* @param typeName - The type that this node should be serialized with.
* @param serializedData - Serialized/transformed data for this node.
* @public
*/
function useType(typeName) {
return new UseType(typeName);
function useType(typeName, serializedData) {
return new UseType(typeName, serializedData);
}
exports.useType = useType;
var UseType = /** @class */ (function () {
function UseType(typeName) {
function UseType(typeName, data) {
this.typeName = typeName;
this.data = data;
}

@@ -25,0 +28,0 @@ return UseType;

import { JSONSchema7 } from 'json-schema';
import { ScrubbrOptions, JSONSchemaDefinitions, TypeSerializer, GenericSerializer } from '.';
declare type ContextObject = Record<string, unknown>;
export default class Scrubbr {

@@ -72,7 +73,7 @@ options: ScrubbrOptions;

*/
setGlobalContext(context: object, merge?: boolean): void;
setGlobalContext(context: ContextObject, merge?: boolean): ContextObject;
/**
* Retrieve the global context object.
*/
getGlobalContext(): object;
getGlobalContext(): ContextObject;
/**

@@ -94,3 +95,3 @@ * Serialize data based on a TypeScript type.

*/
serialize<Type = any>(schemaType: string, data: object, context?: object, options?: ScrubbrOptions): Promise<Type>;
serialize<Type = any>(schemaType: string, data: unknown, context?: ContextObject, options?: ScrubbrOptions): Promise<Type>;
/**

@@ -145,1 +146,2 @@ * Traverse into a node of data on an object to serialize.

}
export {};

@@ -76,3 +76,3 @@ "use strict";

var defaultOptions = {
logLevel: Logger_1.LogLevel.NONE,
logLevel: Logger_1.LogLevel.WARN,
logNesting: false,

@@ -186,3 +186,3 @@ logPrefix: '',

var _this = this;
var typeNames = (Array.isArray(typeName)) ? typeName : [typeName];
var typeNames = Array.isArray(typeName) ? typeName : [typeName];
typeNames.forEach(function (name) {

@@ -218,2 +218,3 @@ _this.logger.debug("Adding custom serializer for type: " + name);

}
return this.globalContext;
};

@@ -484,3 +485,3 @@ /**

var others = typeNames.filter(function (n) { return n != chosenType; });
state.logger.warn("Guessing at type '" + chosenType + "' over " + others + " because it has the fewest properties (you can explicitly override this selection with the 'useType()' function.).");
state.logger.warn("Guessing: Using type '" + chosenType + "', instead of '" + others + "', because it has the fewest properties at object path: '" + state.path + "'.\n(You can explicitly override this selection with the 'useType()' function in a custom serializer).");
}

@@ -530,22 +531,41 @@ else {

return __awaiter(this, void 0, void 0, function () {
var _this = this;
var serialized, i, serializerFn, result;
return __generator(this, function (_a) {
if (!this.genericSerializers.length) {
return [2 /*return*/, dataNode];
switch (_a.label) {
case 0:
if (!this.genericSerializers.length) {
return [2 /*return*/, dataNode];
}
state.logger.debug("Running " + this.genericSerializers.length + " generic serializers");
serialized = dataNode;
i = 0;
_a.label = 1;
case 1:
if (!(i < this.genericSerializers.length)) return [3 /*break*/, 4];
serializerFn = this.genericSerializers[i];
return [4 /*yield*/, serializerFn.call(null, serialized, state)];
case 2:
result = _a.sent();
if (typeof result === 'undefined') {
state.logger.warn("Generic serializer returned 'undefined' at object path: " + state.path);
}
if (result instanceof helpers_1.UseType) {
state.logger.debug("Overriding type: '" + result.typeName + "'");
if (result.typeName === state.schemaType) {
state.logger.warn("Trying to override type with the same type ('" + result.typeName + "') at object path: " + state.path);
}
if (typeof result.data !== 'undefined') {
serialized = result.data;
}
state = this.setStateSchemaDefinition(result.typeName, state);
}
else {
serialized = result;
}
_a.label = 3;
case 3:
i++;
return [3 /*break*/, 1];
case 4: return [2 /*return*/, serialized];
}
state.logger.debug("Running " + this.genericSerializers.length + " generic serializers");
return [2 /*return*/, this.genericSerializers.reduce(function (promise, serializerFn) {
return promise.then(function (data) {
var serialized = serializerFn(data, state);
if (serialized instanceof helpers_1.UseType) {
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);
return data;
}
return serialized;
});
}, Promise.resolve(dataNode))];
});

@@ -559,3 +579,3 @@ });

return __awaiter(this, void 0, void 0, function () {
var typeName, serializerFns, i, serialized, typeName_1, circularRef;
var typeName, serializerFns, serialized, i, result, circularRef;
return __generator(this, function (_a) {

@@ -577,28 +597,36 @@ switch (_a.label) {

state.logger.debug("Running " + serializerFns.length + " serializers for type '" + typeName + "'");
serialized = dataNode;
i = 0;
_a.label = 1;
case 1:
if (!(i < serializerFns.length)) return [3 /*break*/, 7];
if (!(i < serializerFns.length)) return [3 /*break*/, 8];
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*/, 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);
result = _a.sent();
if (typeof result === 'undefined') {
state.logger.warn("Serializer for type '" + typeName + "' returned 'undefined' at object path: " + state.path);
}
if (!(result instanceof helpers_1.UseType)) return [3 /*break*/, 6];
state.logger.debug("Overriding type: '" + typeName + "'");
// Serialized data
if (typeof result.data !== 'undefined') {
serialized = result.data;
}
if (!(result.typeName === state.schemaType)) return [3 /*break*/, 3];
state.logger.warn("Trying to override type with the same type ('" + result.typeName + "') at object path: " + state.path);
return [3 /*break*/, 5];
case 3:
circularRef = this.isCircularReference(typeName_1, state);
circularRef = this.isCircularReference(result.typeName, state);
if (!!circularRef) return [3 /*break*/, 5];
state = this.setStateSchemaDefinition(typeName_1, state);
return [4 /*yield*/, this.runTypeSerializers(dataNode, state)];
state = this.setStateSchemaDefinition(result.typeName, state);
return [4 /*yield*/, this.runTypeSerializers(serialized, state)];
case 4: return [2 /*return*/, _a.sent()];
case 5:
dataNode = serialized;
_a.label = 6;
case 5: return [3 /*break*/, 7];
case 6:
serialized = result;
_a.label = 7;
case 7:
i++;
return [3 /*break*/, 1];
case 7: return [2 /*return*/, dataNode];
case 8: return [2 /*return*/, serialized];
}

@@ -623,3 +651,5 @@ });

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;
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) {

@@ -626,0 +656,0 @@ throw new Error(message);

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

*/
export declare type TypeSerializer = (data: any, state: ScrubbrState) => any | Promise<any>;
export declare type TypeSerializer = (data: unknown, state: ScrubbrState) => unknown | Promise<unknown>;
/**

@@ -14,3 +14,3 @@ * Serializer called for each node within the data object that is being serialized.

*/
export declare type GenericSerializer = (data: any, state: ScrubbrState) => any | Promise<any>;
export declare type GenericSerializer = (data: unknown, state: ScrubbrState) => unknown | Promise<unknown>;
/**

@@ -22,3 +22,3 @@ * Options passed to the Scrubbr constructor

* Set the logger level: LogLevel.NONE, LogLevel.ERROR, LogLevel.WARN, LogLevel.INFO, LogLevel.DEBUG
* @defaultValue LogLevel.NONE
* @defaultValue LogLevel.WARN
* @public

@@ -25,0 +25,0 @@ */

@@ -10,2 +10,3 @@ # Troubleshooting

```
This is the [JSON schema](https://json-schema.org/understanding-json-schema/) that was created from your TypeScript file.

@@ -39,1 +40,36 @@

```
## Understanding the warning: _"Guessing: Using type 'xyz', instead of 'abc' , because it has the fewest properties"_
```
Guessing: Using type 'UserPublic', instead of 'UserRestricted', because it has the fewest properties at object path: 'user'.
(You can explicitly override this selection with the 'useType()' function in a custom serializer).
```
This warning happens when you have a type like this:
```typescript
type Payload = {
user: UserPublic | UserRestricted;
};
```
When Scrubbr gets to the `user` property, it doesn't know exactly how to choose between `UserPublic` and `UserRestricted` and so it makes a guess and chooses the type that defines the fewest properties (most restrictive). In the interest of performance, Scrubbr avoids doing deep introspection and type checking.
To avoid this warning, use a type alias return the `useType` function in a serializer:
```typescript
type Payload = {
user: User;
};
type User = UserPublic | UserRestricted;
```
```typescript
scrubbr.addTypeSerializer('User', (data, state) => {
if (/* type choosing logic here */) {
return useType('UserRestricted');
}
return useType('UserPublic');
}
```
{
"name": "scrubbr",
"version": "0.0.1-alpha.9",
"version": "0.0.1-alpha.10",
"description": "Serialize and sanitize JSON data using TypeScript.",

@@ -5,0 +5,0 @@ "repository": "https://github.com/jgillick/scrubbr",

@@ -11,6 +11,8 @@ /**

*
* @param typeName - The type that this node should be serialized with.
* @param serializedData - Serialized/transformed data for this node.
* @public
*/
export function useType(typeName: string): UseType {
return new UseType(typeName);
export function useType(typeName: string, serializedData?: unknown): UseType {
return new UseType(typeName, serializedData);
}

@@ -20,5 +22,8 @@

typeName: string;
constructor(typeName: string) {
data: unknown;
constructor(typeName: string, data?: unknown) {
this.typeName = typeName;
this.data = data;
}
}

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

const defaultOptions = {
logLevel: LogLevel.NONE,
logLevel: LogLevel.WARN,
logNesting: false,

@@ -23,3 +23,4 @@ logPrefix: '',

type ObjectNode = Record<string, any>;
type ObjectNode = Record<string, unknown>;
type ContextObject = Record<string, unknown>;

@@ -32,3 +33,3 @@ export default class Scrubbr {

private genericSerializers: GenericSerializer[] = [];
private globalContext: object = {};
private globalContext: ContextObject = {};

@@ -97,3 +98,3 @@ /**

*/
loadSchema(schema: string | JSONSchemaDefinitions) {
loadSchema(schema: string | JSONSchemaDefinitions): void {
// Load typescript file

@@ -136,3 +137,3 @@ if (typeof schema == 'string') {

*/
getSchemaFor(typeName: string): JSONSchema7 | null {
getSchemaFor(typeName: string): JSONSchema7 | null {
const definitions = this.schema?.definitions || {};

@@ -150,4 +151,7 @@ if (typeof definitions[typeName] === 'undefined') {

*/
addTypeSerializer(typeName: string | string[], serializer: TypeSerializer) {
const typeNames = (Array.isArray(typeName)) ? typeName : [typeName];
addTypeSerializer(
typeName: string | string[],
serializer: TypeSerializer
): void {
const typeNames = Array.isArray(typeName) ? typeName : [typeName];
typeNames.forEach((name) => {

@@ -165,3 +169,3 @@ this.logger.debug(`Adding custom serializer for type: ${name}`);

*/
addGenericSerializer(serializer: GenericSerializer) {
addGenericSerializer(serializer: GenericSerializer): void {
this.logger.debug(`Adding generic serializer`);

@@ -178,3 +182,3 @@ this.genericSerializers.push(serializer);

*/
setGlobalContext(context: object, merge: boolean = false) {
setGlobalContext(context: ContextObject, merge = false): ContextObject {
if (merge) {

@@ -188,2 +192,3 @@ this.globalContext = {

}
return this.globalContext;
}

@@ -194,3 +199,3 @@

*/
getGlobalContext() {
getGlobalContext(): ContextObject {
return this.globalContext;

@@ -217,4 +222,4 @@ }

schemaType: string,
data: object,
context: object = {},
data: unknown,
context: ContextObject = {},
options: ScrubbrOptions = {}

@@ -232,4 +237,6 @@ ): Promise<Type> {

...context,
}
this.logger.debug(`Using context: '${JSON.stringify(context, null, ' ')}'`);
};
this.logger.debug(
`Using context: '${JSON.stringify(context, null, ' ')}'`
);

@@ -261,3 +268,3 @@ // Create state

*/
private async walkData(node: Object, state: ScrubbrState): Promise<Object> {
private async walkData(node: unknown, state: ScrubbrState): Promise<unknown> {
const serializedNode = await this.serializeNode(node, state);

@@ -270,3 +277,3 @@

} else if (typeof serializedNode === 'object') {
return await this.walkObjectNode(serializedNode, state);
return await this.walkObjectNode(serializedNode as ObjectNode, state);
}

@@ -284,3 +291,3 @@ return serializedNode;

state: ScrubbrState
): Promise<Object> {
): Promise<unknown> {
const nodeProps = Object.entries(node);

@@ -292,8 +299,13 @@ const schemaProps = state.schemaDef.properties || {};

for (let i = 0; i < nodeProps.length; i++) {
let [name, value] = nodeProps[i];
let propSchema = schemaProps[name] as JSONSchema7;
const [name, value] = nodeProps[i];
const propSchema = schemaProps[name] as JSONSchema7;
const propPath = `${pathPrefix}${name}`;
state.logger.debug(`[PATH] ${propPath}`);
const propState = state.createNodeState(value, name, propPath, propSchema);
const propState = state.createNodeState(
value,
name,
propPath,
propSchema
);

@@ -318,3 +330,6 @@ // Property not defined in the schema, do not serialize property

*/
private async walkArrayNode(node: any[], state: ScrubbrState): Promise<any> {
private async walkArrayNode(
node: unknown[],
state: ScrubbrState
): Promise<unknown> {
const schema = state.schemaDef;

@@ -340,3 +355,3 @@ const listSchema = schema.items as JSONSchema7 | JSONSchema7[];

itemPath,
itemSchema as JSONSchema7,
itemSchema as JSONSchema7
);

@@ -361,3 +376,6 @@

*/
private async serializeNode(data: any, state: ScrubbrState): Promise<Object> {
private async serializeNode(
data: unknown,
state: ScrubbrState
): Promise<unknown> {
const originalDef = state.schemaDef;

@@ -404,3 +422,3 @@

let schemaList = (schema?.allOf ||
const schemaList = (schema?.allOf ||
schema?.anyOf ||

@@ -415,3 +433,3 @@ schema?.oneOf ||

// Get all the types we have definitions for
let foundTypes = new Map<string, JSONSchema7>();
const foundTypes = new Map<string, JSONSchema7>();
schemaList.forEach((schemaRef) => {

@@ -456,3 +474,3 @@ const refPath = schemaRef.$ref;

state.logger.warn(
`Guessing at type '${chosenType}' over ${others} because it has the fewest properties (you can explicitly override this selection with the 'useType()' function.).`
`Guessing: Using type '${chosenType}', instead of '${others}', because it has the fewest properties at object path: '${state.path}'.\n(You can explicitly override this selection with the 'useType()' function in a custom serializer).`
);

@@ -512,5 +530,5 @@ } else {

private async runGenericSerializers(
dataNode: Object,
dataNode: unknown,
state: ScrubbrState
): Promise<Object> {
): Promise<unknown> {
if (!this.genericSerializers.length) {

@@ -524,17 +542,31 @@ return dataNode;

return this.genericSerializers.reduce((promise, serializerFn) => {
return promise.then((data) => {
const serialized = serializerFn(data, state);
if (serialized instanceof UseType) {
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}`);
}
let serialized = dataNode;
for (let i = 0; i < this.genericSerializers.length; i++) {
const serializerFn = this.genericSerializers[i];
const result = await serializerFn.call(null, serialized, state);
state = this.setStateSchemaDefinition(serialized.typeName, state);
return data;
if (typeof result === 'undefined') {
state.logger.warn(
`Generic serializer returned 'undefined' at object path: ${state.path}`
);
}
if (result instanceof UseType) {
state.logger.debug(`Overriding type: '${result.typeName}'`);
if (result.typeName === state.schemaType) {
state.logger.warn(
`Trying to override type with the same type ('${result.typeName}') at object path: ${state.path}`
);
}
return serialized;
});
}, Promise.resolve(dataNode));
if (typeof result.data !== 'undefined') {
serialized = result.data;
}
state = this.setStateSchemaDefinition(result.typeName, state);
} else {
serialized = result;
}
}
return serialized;
}

@@ -546,5 +578,5 @@

private async runTypeSerializers(
dataNode: Object,
dataNode: unknown,
state: ScrubbrState
): Promise<Object> {
): Promise<unknown> {
const typeName = state.schemaType;

@@ -569,25 +601,40 @@ if (!typeName) {

let serialized = dataNode;
for (let i = 0; i < serializerFns.length; i++) {
const serialized = await serializerFns[i].call(null, dataNode, state);
const result = await serializerFns[i].call(null, dataNode, state);
if (typeof result === 'undefined') {
state.logger.warn(
`Serializer for type '${typeName}' returned 'undefined' at object path: ${state.path}`
);
}
// Change type
if (serialized instanceof UseType && serialized.typeName !== typeName) {
const { typeName } = serialized;
if (result instanceof UseType) {
state.logger.debug(`Overriding type: '${typeName}'`);
if (serialized.typeName === state.schemaType) {
state.logger.warn(`Trying to override type with the same type ('${serialized.typeName}') at object path: ${state.path}`);
// Serialized data
if (typeof result.data !== 'undefined') {
serialized = result.data;
}
// No type change
if (result.typeName === state.schemaType) {
state.logger.warn(
`Trying to override type with the same type ('${result.typeName}') at object path: ${state.path}`
);
} else {
// Check for circular reference
const circularRef = this.isCircularReference(typeName, state);
// Stop serializing this type and switch to the new type, if it's not a circular reference
const circularRef = this.isCircularReference(result.typeName, state);
if (!circularRef) {
state = this.setStateSchemaDefinition(typeName, state);
return await this.runTypeSerializers(dataNode, state);
state = this.setStateSchemaDefinition(result.typeName, state);
return await this.runTypeSerializers(serialized, state);
}
}
} else {
serialized = result;
}
dataNode = serialized;
}
return dataNode;
return serialized;
}

@@ -613,3 +660,5 @@

private error(message: string, state?: ScrubbrState) {
const throwOnError = (state) ? state?.options?.throwOnError : this.options.throwOnError;
const throwOnError = state
? state?.options?.throwOnError
: this.options.throwOnError;
if (throwOnError) {

@@ -616,0 +665,0 @@ throw new Error(message);

@@ -10,5 +10,5 @@ import { JSONSchema7 } from 'json-schema';

export type TypeSerializer = (
data: any,
data: unknown,
state: ScrubbrState
) => any | Promise<any>;
) => unknown | Promise<unknown>;

@@ -20,5 +20,5 @@ /**

export type GenericSerializer = (
data: any,
data: unknown,
state: ScrubbrState
) => any | Promise<any>;
) => unknown | Promise<unknown>;

@@ -31,3 +31,3 @@ /**

* Set the logger level: LogLevel.NONE, LogLevel.ERROR, LogLevel.WARN, LogLevel.INFO, LogLevel.DEBUG
* @defaultValue LogLevel.NONE
* @defaultValue LogLevel.WARN
* @public

@@ -34,0 +34,0 @@ */

@@ -104,2 +104,24 @@ import 'jest';

});
test('override type and transform node', async () => {
serializerFn.mockImplementation((data, state) => {
if (state.path == 'child') {
const newData = {
node: 'boo',
extra: 'woo',
};
return useType('GenericSerializerExtended', newData);
}
return data;
});
const serialized = await scrubbr.serialize('GenericSerializerTest', {
child: {
node: 'foo',
extra: 'bar',
},
});
expect(serialized.child.node).toBe('boo');
expect(serialized.child.extra).toBe('woo');
});
});

@@ -45,2 +45,17 @@ import 'jest';

test('override type and transform node', async () => {
scrubbr.addTypeSerializer('TargetTypeA', () => {
const newData = {
value: 'boo',
};
return useType('TargetTypeB', newData);
});
const data = {
node: { value: 'foo' },
};
const serialized = await scrubbr.serialize('TypeSerializerTest', data);
expect(serialized.node.value).toBe('boo');
});
test('union type', async () => {

@@ -82,3 +97,3 @@ const typeASerializerFn = jest.fn((data, _state) => data);

expect(Array.from(receivedTypes)).toEqual(['TargetTypeA', 'TargetTypeB']);
})
});
});

@@ -1,18 +0,18 @@

type SimpleTypeUnion = {
value: OptionOne | OptionTwo;
type UnionTypeTestSimple = {
value: UnionTypeTestType1 | UnionTypeTestType2;
};
type PrimitiveUnion = {
type UnionTypeTestPrimitive = {
value: string | boolean;
};
type MixedUnion = {
value: OptionOne | null;
type UnionTypeTestMixed = {
value: UnionTypeTestType1 | null;
};
type UnionAlias = {
type UnionTypeTestAlias = {
value: AliasedUnion;
};
type OptionOne = {
type UnionTypeTestType1 = {
nodeA: string;

@@ -22,6 +22,6 @@ nodeB: string;

type OptionTwo = {
type UnionTypeTestType2 = {
nodeA: string;
};
type AliasedUnion = OptionOne | OptionTwo;
type AliasedUnion = UnionTypeTestType1 | UnionTypeTestType2;
import 'jest';
import Scrubbr, { useType, ScrubbrState } from '../src/';
import Scrubbr, { useType, ScrubbrState, LogLevel } from '../src/';
describe('Union types', () => {
const pathTypes = new Map<string, string | null>();
let scrubbr: Scrubbr;
let pathTypes = new Map<string, string | null>();
let firstSerializerFn: jest.Mock;

@@ -12,6 +12,8 @@

// Override this later
firstSerializerFn = jest.fn((data: any) => data);
scrubbr.addGenericSerializer(firstSerializerFn);
// Track what type is chosen for ever path node
firstSerializerFn = jest.fn((data: any, _state: ScrubbrState) => data);
scrubbr.addGenericSerializer(firstSerializerFn);
scrubbr.addGenericSerializer((data: any, state: ScrubbrState) => {
scrubbr.addGenericSerializer((data: unknown, state: ScrubbrState) => {
pathTypes.set(state.path, state.schemaType);

@@ -23,3 +25,3 @@ return data;

test('automatically choose between two types', async () => {
await scrubbr.serialize('SimpleTypeUnion', {
await scrubbr.serialize('UnionTypeTestSimple', {
value: {

@@ -32,7 +34,7 @@ nodeA: 'foo',

// OptionTwo has fewer properties
expect(pathTypes.get('value')).toBe('OptionTwo');
expect(pathTypes.get('value')).toBe('UnionTypeTestType2');
});
test('choose between primitive types', async () => {
await scrubbr.serialize('PrimitiveUnion', { value: 'test' });
await scrubbr.serialize('UnionTypeTestPrimitive', { value: 'test' });
expect(pathTypes.get('value')).toBe(null);

@@ -42,8 +44,8 @@ });

test('union between TypeScript type and primitive', async () => {
await scrubbr.serialize('MixedUnion', { value: 'test' });
expect(pathTypes.get('value')).toBe('OptionOne');
await scrubbr.serialize('UnionTypeTestMixed', { value: 'test' });
expect(pathTypes.get('value')).toBe('UnionTypeTestType1');
});
test('Aliased union type', async () => {
await scrubbr.serialize('UnionAlias', {
await scrubbr.serialize('UnionTypeTestAlias', {
value: {

@@ -54,3 +56,3 @@ nodeA: 'foo',

});
expect(pathTypes.get('value')).toBe('OptionTwo');
expect(pathTypes.get('value')).toBe('UnionTypeTestType2');
});

@@ -61,7 +63,8 @@

if (state.path == 'value') {
return useType('OptionOne');
return useType('UnionTypeTestType1');
}
return data;
});
const output = await scrubbr.serialize('SimpleTypeUnion', {
const output = await scrubbr.serialize('UnionTypeTestSimple', {
value: {

@@ -72,6 +75,29 @@ nodeA: 'foo',

});
expect(pathTypes.get('value')).toBe('OptionOne');
expect(pathTypes.get('value')).toBe('UnionTypeTestType1');
expect(output.value.nodeA).toBe('foo');
expect(output.value.nodeB).toBe('bar');
});
// test('change type and override value', async () => {
// firstSerializerFn.mockImplementation((data, state) => {
// if (state.path == 'value') {
// const newNodeData = {
// nodeA: 'baz',
// nodeB: 'boo',
// };
// return useType('UnionTypeTestType1', newNodeData);
// }
// return data;
// });
// const output = await scrubbr.serialize('UnionTypeTestSimple', {
// value: {
// nodeA: 'foo',
// nodeB: 'bar',
// },
// });
// expect(pathTypes.get('value')).toBe('UnionTypeTestType1');
// expect(output.value.nodeA).toBe('baz');
// expect(output.value.nodeB).toBe('boo');
// });
});

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