Skip to content

Commit

Permalink
fix: generify check for “native code”
Browse files Browse the repository at this point in the history
The checks for native code using `endsWith(‘{ [native code] }’)` do not work in Safari when code is packaged using webpack because Safari includs newlines in its native code output.

All native code checks have been centralized to a `isNativeCode` function exported from util and the check now uses a regex that allows for any type of white space.
  • Loading branch information
kdubb committed Jul 23, 2020
1 parent adb7bd3 commit 2c34d2b
Show file tree
Hide file tree
Showing 15 changed files with 46 additions and 35 deletions.
4 changes: 2 additions & 2 deletions src/decorators/JsonAlias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module Decorators
*/

import {defineMetadata, makeJacksonDecorator} from '../util';
import {defineMetadata, isNativeCode, makeJacksonDecorator} from '../util';
import {JsonAliasDecorator, JsonAliasOptions} from '../@types';

/**
Expand Down Expand Up @@ -39,7 +39,7 @@ export const JsonAlias: JsonAliasDecorator = makeJacksonDecorator(
}
if (descriptorOrParamIndex != null && typeof descriptorOrParamIndex === 'number') {
defineMetadata('JsonAliasParam',
options, (target.constructor.toString().endsWith('{ [native code] }')) ? target : target.constructor,
options, (isNativeCode(target.constructor)) ? target : target.constructor,
(propertyKey) ? propertyKey : 'constructor', {
suffix: descriptorOrParamIndex.toString()
});
Expand Down
4 changes: 2 additions & 2 deletions src/decorators/JsonClassType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module Decorators
*/

import {defineMetadata, makeJacksonDecorator} from '../util';
import {defineMetadata, isNativeCode, makeJacksonDecorator} from '../util';
import {JsonClassTypeDecorator, JsonClassTypeOptions} from '../@types';

/**
Expand Down Expand Up @@ -46,7 +46,7 @@ export const JsonClassType: JsonClassTypeDecorator = makeJacksonDecorator(
if (descriptorOrParamIndex != null && typeof descriptorOrParamIndex === 'number') {
defineMetadata(
'JsonClassTypeParam',
options, (target.constructor.toString().endsWith('{ [native code] }')) ? target : target.constructor,
options, (isNativeCode(target.constructor)) ? target : target.constructor,
(propertyKey) ? propertyKey : 'constructor', {
suffix: descriptorOrParamIndex.toString()
});
Expand Down
4 changes: 2 additions & 2 deletions src/decorators/JsonDeserialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module Decorators
*/

import {defineMetadata, makeJacksonDecorator} from '../util';
import {defineMetadata, isNativeCode, makeJacksonDecorator} from '../util';
import {JsonDeserializeDecorator, JsonDeserializeOptions} from '../@types';

/**
Expand Down Expand Up @@ -49,7 +49,7 @@ export const JsonDeserialize: JsonDeserializeDecorator = makeJacksonDecorator(
if (descriptorOrParamIndex != null && typeof descriptorOrParamIndex === 'number') {
defineMetadata(
'JsonDeserializeParam',
options, (target.constructor.toString().endsWith('{ [native code] }')) ? target : target.constructor,
options, (isNativeCode(target.constructor)) ? target : target.constructor,
(propertyKey) ? propertyKey : 'constructor', {
suffix: descriptorOrParamIndex.toString()
});
Expand Down
4 changes: 2 additions & 2 deletions src/decorators/JsonIdentityInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module Decorators
*/

import {defineMetadata, makeJacksonDecorator} from '../util';
import {defineMetadata, isNativeCode, makeJacksonDecorator} from '../util';
import {
JsonIdentityInfoDecorator,
JsonIdentityInfoOptions
Expand Down Expand Up @@ -106,7 +106,7 @@ export const JsonIdentityInfo: JsonIdentityInfoDecorator = makeJacksonDecorator(
if (descriptorOrParamIndex != null && typeof descriptorOrParamIndex === 'number') {
defineMetadata(
'JsonIdentityInfoParam',
options, (target.constructor.toString().endsWith('{ [native code] }')) ? target : target.constructor,
options, (isNativeCode(target.constructor)) ? target : target.constructor,
(propertyKey) ? propertyKey : 'constructor', {
suffix: descriptorOrParamIndex.toString()
});
Expand Down
4 changes: 2 additions & 2 deletions src/decorators/JsonIdentityReference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module Decorators
*/

import {defineMetadata, makeJacksonDecorator} from '../util';
import {defineMetadata, isNativeCode, makeJacksonDecorator} from '../util';
import {
JsonIdentityReferenceDecorator,
JsonIdentityReferenceOptions
Expand Down Expand Up @@ -61,7 +61,7 @@ export const JsonIdentityReference: JsonIdentityReferenceDecorator = makeJackson
if (descriptorOrParamIndex != null && typeof descriptorOrParamIndex === 'number') {
defineMetadata(
'JsonIdentityReferenceParam',
options, (target.constructor.toString().endsWith('{ [native code] }')) ? target : target.constructor,
options, (isNativeCode(target.constructor)) ? target : target.constructor,
(propertyKey) ? propertyKey : 'constructor', {
suffix: descriptorOrParamIndex.toString()
});
Expand Down
4 changes: 2 additions & 2 deletions src/decorators/JsonIgnore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module Decorators
*/

import {defineMetadata, makeJacksonDecorator} from '../util';
import {defineMetadata, isNativeCode, makeJacksonDecorator} from '../util';
import {JsonIgnoreDecorator, JsonIgnoreOptions} from '../@types';

/**
Expand Down Expand Up @@ -33,7 +33,7 @@ export const JsonIgnore: JsonIgnoreDecorator = makeJacksonDecorator(
}
if (descriptorOrParamIndex != null && typeof descriptorOrParamIndex === 'number') {
defineMetadata('JsonIgnoreParam',
options, (target.constructor.toString().endsWith('{ [native code] }')) ? target : target.constructor,
options, (isNativeCode(target.constructor)) ? target : target.constructor,
(propertyKey) ? propertyKey : 'constructor', {
suffix: descriptorOrParamIndex.toString()
});
Expand Down
4 changes: 2 additions & 2 deletions src/decorators/JsonIgnoreProperties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module Decorators
*/

import {defineMetadata, makeJacksonDecorator} from '../util';
import {defineMetadata, isNativeCode, makeJacksonDecorator} from '../util';
import {JsonIgnorePropertiesDecorator, JsonIgnorePropertiesOptions} from '../@types';

/**
Expand Down Expand Up @@ -48,7 +48,7 @@ export const JsonIgnoreProperties: JsonIgnorePropertiesDecorator = makeJacksonDe
if (descriptorOrParamIndex != null && typeof descriptorOrParamIndex === 'number') {
defineMetadata(
'JsonIgnorePropertiesParam',
options, (target.constructor.toString().endsWith('{ [native code] }')) ? target : target.constructor,
options, (isNativeCode(target.constructor)) ? target : target.constructor,
(propertyKey) ? propertyKey : 'constructor', {
suffix: descriptorOrParamIndex.toString()
});
Expand Down
6 changes: 3 additions & 3 deletions src/decorators/JsonInject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module Decorators
*/

import {defineMetadata, getArgumentNames, makeJacksonDecorator} from '../util';
import {defineMetadata, getArgumentNames, isNativeCode, makeJacksonDecorator} from '../util';
import {JsonInjectDecorator, JsonInjectOptions} from '../@types';
import {JacksonError} from '../core/JacksonError';

Expand Down Expand Up @@ -56,7 +56,7 @@ export const JsonInject: JsonInjectDecorator = makeJacksonDecorator(
}

defineMetadata('JsonInjectParam',
options, (target.constructor.toString().endsWith('{ [native code] }')) ? target : target.constructor,
options, (isNativeCode(target.constructor)) ? target : target.constructor,
(propertyKey) ? propertyKey : 'constructor', {
suffix: descriptorOrParamIndex.toString()
});
Expand All @@ -73,7 +73,7 @@ export const JsonInject: JsonInjectDecorator = makeJacksonDecorator(
}
if (!options.value) {
// eslint-disable-next-line max-len
throw new JacksonError(`Invalid usage of @JsonInject() on ${((target.constructor.toString().endsWith('{ [native code] }')) ? target : target.constructor).name}.${propertyKey.toString()}. You must either define a non-empty @JsonInject() option value or change the method name starting with "get" for Getters or "set" for Setters.`);
throw new JacksonError(`Invalid usage of @JsonInject() on ${((isNativeCode(target.constructor)) ? target : target.constructor).name}.${propertyKey.toString()}. You must either define a non-empty @JsonInject() option value or change the method name starting with "get" for Getters or "set" for Setters.`);
}
}
defineMetadata('JsonInject', options, target.constructor, propertyKey);
Expand Down
6 changes: 3 additions & 3 deletions src/decorators/JsonProperty.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module Decorators
*/

import {defineMetadata, getArgumentNames, makeJacksonDecorator} from '../util';
import {defineMetadata, getArgumentNames, isNativeCode, makeJacksonDecorator} from '../util';
import {JsonPropertyDecorator, JsonPropertyOptions} from '../@types';
import {JacksonError} from '../core/JacksonError';

Expand Down Expand Up @@ -90,7 +90,7 @@ export const JsonProperty: JsonPropertyDecorator = makeJacksonDecorator(
}
if (!options.value) {
// eslint-disable-next-line max-len
throw new JacksonError(`Invalid usage of @JsonProperty() on ${((target.constructor.toString().endsWith('{ [native code] }')) ? target : target.constructor).name}.${propertyKey.toString()}. You must either define a non-empty @JsonProperty() option value or change the method name starting with "get" for Getters or "set" for Setters.`);
throw new JacksonError(`Invalid usage of @JsonProperty() on ${(isNativeCode(target.constructor) ? target : target.constructor).name}.${propertyKey.toString()}. You must either define a non-empty @JsonProperty() option value or change the method name starting with "get" for Getters or "set" for Setters.`);
}
} else {
options.value = propertyKey.toString();
Expand All @@ -106,7 +106,7 @@ export const JsonProperty: JsonPropertyDecorator = makeJacksonDecorator(

defineMetadata(
'JsonPropertyParam',
options, (target.constructor.toString().endsWith('{ [native code] }')) ? target : target.constructor,
options, isNativeCode(target.constructor) ? target : target.constructor,
(propertyKey) ? propertyKey : 'constructor', {
suffix: descriptorOrParamIndex.toString()
});
Expand Down
4 changes: 2 additions & 2 deletions src/decorators/JsonPropertyOrder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module Decorators
*/

import {makeJacksonDecorator, defineMetadata} from '../util';
import {makeJacksonDecorator, defineMetadata, isNativeCode} from '../util';
import {JsonPropertyOrderDecorator, JsonPropertyOrderOptions} from '../@types';

/**
Expand Down Expand Up @@ -45,7 +45,7 @@ export const JsonPropertyOrder: JsonPropertyOrderDecorator = makeJacksonDecorato
if (descriptorOrParamIndex != null && typeof descriptorOrParamIndex === 'number') {
defineMetadata(
'JsonPropertyOrderParam',
options, (target.constructor.toString().endsWith('{ [native code] }')) ? target : target.constructor,
options, (isNativeCode(target.constructor)) ? target : target.constructor,
(propertyKey) ? propertyKey : 'constructor', {
suffix: descriptorOrParamIndex.toString()
});
Expand Down
4 changes: 2 additions & 2 deletions src/decorators/JsonSubTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module Decorators
*/

import {makeJacksonDecorator, defineMetadata} from '../util';
import {makeJacksonDecorator, defineMetadata, isNativeCode} from '../util';
import {JsonSubTypesDecorator, JsonSubTypesOptions} from '../@types';

/**
Expand Down Expand Up @@ -51,7 +51,7 @@ export const JsonSubTypes: JsonSubTypesDecorator = makeJacksonDecorator(
if (descriptorOrParamIndex != null && typeof descriptorOrParamIndex === 'number') {
defineMetadata(
'JsonSubTypesParam',
options, (target.constructor.toString().endsWith('{ [native code] }')) ? target : target.constructor,
options, (isNativeCode(target.constructor)) ? target : target.constructor,
(propertyKey) ? propertyKey : 'constructor', {
suffix: descriptorOrParamIndex.toString()
});
Expand Down
4 changes: 2 additions & 2 deletions src/decorators/JsonTypeIdResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module Decorators
*/

import {defineMetadata, makeJacksonDecorator} from '../util';
import {defineMetadata, isNativeCode, makeJacksonDecorator} from '../util';
import {JsonTypeIdResolverDecorator, JsonTypeIdResolverOptions} from '../@types';

/**
Expand Down Expand Up @@ -62,7 +62,7 @@ export const JsonTypeIdResolver: JsonTypeIdResolverDecorator = makeJacksonDecora
if (descriptorOrParamIndex != null && typeof descriptorOrParamIndex === 'number') {
defineMetadata(
'JsonTypeIdResolverParam',
options, (target.constructor.toString().endsWith('{ [native code] }')) ? target : target.constructor,
options, (isNativeCode(target.constructor)) ? target : target.constructor,
(propertyKey) ? propertyKey : 'constructor', {
suffix: descriptorOrParamIndex.toString()
});
Expand Down
4 changes: 2 additions & 2 deletions src/decorators/JsonTypeInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module Decorators
*/

import {defineMetadata, makeJacksonDecorator} from '../util';
import {defineMetadata, isNativeCode, makeJacksonDecorator} from '../util';
import {JsonTypeInfoDecorator, JsonTypeInfoOptions} from '../@types';

/**
Expand Down Expand Up @@ -94,7 +94,7 @@ export const JsonTypeInfo: JsonTypeInfoDecorator = makeJacksonDecorator(
if (descriptorOrParamIndex != null && typeof descriptorOrParamIndex === 'number') {
defineMetadata(
'JsonTypeInfoParam',
options, (target.constructor.toString().endsWith('{ [native code] }')) ? target : target.constructor,
options, (isNativeCode(target.constructor)) ? target : target.constructor,
(propertyKey) ? propertyKey : 'constructor', {
suffix: descriptorOrParamIndex.toString()
});
Expand Down
4 changes: 2 additions & 2 deletions src/decorators/JsonView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* @module Decorators
*/

import {defineMetadata, makeJacksonDecorator} from '../util';
import {defineMetadata, isNativeCode, makeJacksonDecorator} from '../util';
import {JsonViewDecorator, JsonViewOptions} from '../@types';

/**
Expand Down Expand Up @@ -65,7 +65,7 @@ export const JsonView: JsonViewDecorator = makeJacksonDecorator(
if (descriptorOrParamIndex != null && typeof descriptorOrParamIndex === 'number') {
defineMetadata(
'JsonViewParam',
options, (target.constructor.toString().endsWith('{ [native code] }')) ? target : target.constructor,
options, (isNativeCode(target.constructor)) ? target : target.constructor,
(propertyKey) ? propertyKey : 'constructor', {
suffix: descriptorOrParamIndex.toString()
});
Expand Down
21 changes: 16 additions & 5 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,8 @@ export const getClassProperties = (target: Record<string, any>, obj: any = null,
objKeys = Object.keys(obj);
if (objKeys.includes('constructor') &&
typeof obj.constructor === 'function' &&
!obj.constructor.toString().endsWith('{ [native code] }') &&
obj.constructor.constructor.toString().endsWith('{ [native code] }')) {
!isNativeCode(obj.constructor) &&
isNativeCode(obj.constructor.constructor)) {
objKeys.splice(objKeys.indexOf('constructor'), 1);
}
}
Expand Down Expand Up @@ -496,7 +496,7 @@ export const mapClassPropertyToVirtualProperty =
export const getArgumentNames = (method): string[] => {
let code = method.toString().trim();

if (code.endsWith(' { [native code] }')) {
if (isNativeCode(code)) {
return [];
}

Expand Down Expand Up @@ -891,8 +891,8 @@ export const getObjectKeysWithPropertyDescriptorNames = (obj: any, ctor: any,

if (keys.includes('constructor') &&
typeof obj.constructor === 'function' &&
!obj.constructor.toString().endsWith('{ [native code] }') &&
obj.constructor.constructor.toString().endsWith('{ [native code] }')) {
!isNativeCode(obj.constructor) &&
isNativeCode(obj.constructor.constructor)) {
keys.splice(keys.indexOf('constructor'), 1);
}

Expand Down Expand Up @@ -953,3 +953,14 @@ export const castObjLiteral = (target: any, value: any): any => {
*/
export const sortMappersByOrder = <T>(mappers: CustomMapper<T>[]): CustomMapper<T>[] =>
mappers.sort((a, b) => a.order - b.order > 0 ? 1 : -1);


const nativeCodeRegex = /{\s*\[native code]\s*}$/;

/**
* Determines if the provided function is implemented in native code.
*
* @param value
* @internal
*/
export const isNativeCode = (value: Function | string): boolean => !!nativeCodeRegex.exec(value.toString());

0 comments on commit 2c34d2b

Please sign in to comment.