diff --git a/packages/optimizely-sdk/.eslintrc.js b/packages/optimizely-sdk/.eslintrc.js index b90f645cf..2c4fe5fd9 100644 --- a/packages/optimizely-sdk/.eslintrc.js +++ b/packages/optimizely-sdk/.eslintrc.js @@ -4,7 +4,10 @@ module.exports = { commonjs: true, node: true, }, - extends: 'eslint:recommended', + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + ], globals: { Atomics: 'readonly', SharedArrayBuffer: 'readonly', @@ -14,7 +17,18 @@ module.exports = { ecmaVersion: 6, sourceType: 'module', }, + overrides: [ + { + 'files': ['*.ts'], + 'rules': { + '@typescript-eslint/explicit-module-boundary-types': ['error'] + } + } + ], rules: { 'no-prototype-builtins': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-empty-function': 'off', + 'no-shadow': 'error', }, }; diff --git a/packages/optimizely-sdk/karma.base.conf.js b/packages/optimizely-sdk/karma.base.conf.js index c4ff7a400..d6beb7668 100644 --- a/packages/optimizely-sdk/karma.base.conf.js +++ b/packages/optimizely-sdk/karma.base.conf.js @@ -24,6 +24,18 @@ module.exports = { webpack: { mode: 'production', + module: { + rules: [ + { + test: /\.[tj]s$/, + use: 'ts-loader', + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: ['.ts', '.js'], + }, }, //browserStack setup diff --git a/packages/optimizely-sdk/lib/core/decision_service/index.js b/packages/optimizely-sdk/lib/core/decision_service/index.js index 6f5686fb1..6b0028da8 100644 --- a/packages/optimizely-sdk/lib/core/decision_service/index.js +++ b/packages/optimizely-sdk/lib/core/decision_service/index.js @@ -20,7 +20,7 @@ import enums from '../../utils/enums'; import fns from '../../utils/fns'; import projectConfig from '../project_config'; import AudienceEvaluator from '../audience_evaluator'; -import stringValidator from '../../utils/string_value_validator'; +import * as stringValidator from '../../utils/string_value_validator'; var MODULE_NAME = 'DECISION_SERVICE'; var ERROR_MESSAGES = enums.ERROR_MESSAGES; diff --git a/packages/optimizely-sdk/lib/core/decision_service/index.tests.js b/packages/optimizely-sdk/lib/core/decision_service/index.tests.js index 7d51fec26..8551d87ae 100644 --- a/packages/optimizely-sdk/lib/core/decision_service/index.tests.js +++ b/packages/optimizely-sdk/lib/core/decision_service/index.tests.js @@ -32,7 +32,7 @@ import AudienceEvaluator from '../audience_evaluator'; import errorHandler from '../../plugins/error_handler'; import eventBuilder from '../../core/event_builder/index.js'; import eventDispatcher from '../../plugins/event_dispatcher/index.node'; -import jsonSchemaValidator from '../../utils/json_schema_validator'; +import * as jsonSchemaValidator from '../../utils/json_schema_validator'; import { getTestProjectConfig, getTestProjectConfigWithFeatures, diff --git a/packages/optimizely-sdk/lib/core/event_builder/event_helpers.js b/packages/optimizely-sdk/lib/core/event_builder/event_helpers.js index 778efa662..65aaf2e1f 100644 --- a/packages/optimizely-sdk/lib/core/event_builder/event_helpers.js +++ b/packages/optimizely-sdk/lib/core/event_builder/event_helpers.js @@ -17,8 +17,8 @@ import { getLogger } from '@optimizely/js-sdk-logging'; import fns from '../../utils/fns'; import projectConfig from '../project_config'; -import eventTagUtils from '../../utils/event_tag_utils'; -import attributesValidator from'../../utils/attributes_validator'; +import * as eventTagUtils from '../../utils/event_tag_utils'; +import * as attributesValidator from'../../utils/attributes_validator'; var logger = getLogger('EVENT_BUILDER'); @@ -106,6 +106,14 @@ export var buildConversionEvent = function(config) { var eventTags = config.eventTags; var eventId = projectConfig.getEventId(configObj, eventKey); + let revenue = null; + let eventValue = null; + + if (eventTags) { + revenue = eventTagUtils.getRevenueValue(eventTags, logger); + eventValue = eventTagUtils.getEventValue(eventTags, logger); + } + return { type: 'conversion', timestamp: fns.currentTimestamp(), @@ -131,8 +139,8 @@ export var buildConversionEvent = function(config) { key: eventKey, }, - revenue: eventTagUtils.getRevenueValue(eventTags, logger), - value: eventTagUtils.getEventValue(eventTags, logger), + revenue: revenue, + value: eventValue, tags: eventTags, }; }; diff --git a/packages/optimizely-sdk/lib/core/event_builder/index.js b/packages/optimizely-sdk/lib/core/event_builder/index.js index 08cb0225e..f7f78d57c 100644 --- a/packages/optimizely-sdk/lib/core/event_builder/index.js +++ b/packages/optimizely-sdk/lib/core/event_builder/index.js @@ -16,8 +16,8 @@ import fns from '../../utils/fns'; import enums from '../../utils/enums'; import projectConfig from '../project_config'; -import eventTagUtils from '../../utils/event_tag_utils'; -import attributeValidator from '../../utils/attributes_validator'; +import * as eventTagUtils from '../../utils/event_tag_utils'; +import * as attributeValidator from '../../utils/attributes_validator'; var ACTIVATE_EVENT_KEY = 'campaign_activated'; var CUSTOM_ATTRIBUTE_FEATURE_TYPE = 'custom'; diff --git a/packages/optimizely-sdk/lib/core/project_config/project_config_manager.tests.js b/packages/optimizely-sdk/lib/core/project_config/project_config_manager.tests.js index de38044ea..e43b95fc5 100644 --- a/packages/optimizely-sdk/lib/core/project_config/project_config_manager.tests.js +++ b/packages/optimizely-sdk/lib/core/project_config/project_config_manager.tests.js @@ -25,7 +25,7 @@ import { ERROR_MESSAGES, LOG_MESSAGES } from '../../utils/enums'; import testData from '../../tests/test_data'; import * as optimizelyConfig from '../optimizely_config/index'; import projectConfigManager from './project_config_manager'; -import jsonSchemaValidator from '../../utils/json_schema_validator'; +import * as jsonSchemaValidator from '../../utils/json_schema_validator'; describe('lib/core/project_config/project_config_manager', function() { var globalStubErrorHandler; diff --git a/packages/optimizely-sdk/lib/core/project_config/project_config_schema.js b/packages/optimizely-sdk/lib/core/project_config/project_config_schema.ts similarity index 97% rename from packages/optimizely-sdk/lib/core/project_config/project_config_schema.js rename to packages/optimizely-sdk/lib/core/project_config/project_config_schema.ts index d04959b0d..e21830b89 100644 --- a/packages/optimizely-sdk/lib/core/project_config/project_config_schema.js +++ b/packages/optimizely-sdk/lib/core/project_config/project_config_schema.ts @@ -17,7 +17,9 @@ /** * Project Config JSON Schema file used to validate the project json datafile */ -export var schema = { + import { JSONSchema4 } from 'json-schema'; + + var schemaDefinition = { $schema: 'http://json-schema.org/draft-04/schema#', type: 'object', properties: { @@ -276,4 +278,6 @@ export var schema = { }, }; -export default schema; +const schema = schemaDefinition as JSONSchema4 + +export default schema diff --git a/packages/optimizely-sdk/lib/index.d.ts b/packages/optimizely-sdk/lib/index.d.ts index 1d34c93b2..af31fabaa 100644 --- a/packages/optimizely-sdk/lib/index.d.ts +++ b/packages/optimizely-sdk/lib/index.d.ts @@ -39,6 +39,8 @@ declare module '@optimizely/optimizely-sdk' { // The options object given to Optimizely.createInstance. export interface Config { + // TODO[OASIS-6649]: Don't use object type + // eslint-disable-next-line @typescript-eslint/ban-types datafile?: object | string; datafileOptions?: DatafileOptions; errorHandler?: ErrorHandler; @@ -50,6 +52,8 @@ declare module '@optimizely/optimizely-sdk' { | enums.LOG_LEVEL.INFO | enums.LOG_LEVEL.NOTSET | enums.LOG_LEVEL.WARNING; + // TODO[OASIS-6649]: Don't use object type + // eslint-disable-next-line @typescript-eslint/ban-types jsonSchemaValidator?: object; userProfileService?: UserProfileService | null; eventBatchSize?: number; @@ -115,6 +119,8 @@ declare module '@optimizely/optimizely-sdk' { // HTTP method with which to send the event. httpVerb: 'POST'; // Value to send in the request body, JSON-serialized. + // TODO[OASIS-6649]: Don't use any type + // eslint-disable-next-line @typescript-eslint/no-explicit-any params: any; } @@ -159,6 +165,8 @@ declare module '@optimizely/optimizely-sdk' { } export type UserAttributes = { + // TODO[OASIS-6649]: Don't use any type + // eslint-disable-next-line @typescript-eslint/no-explicit-any [name: string]: any; }; @@ -183,6 +191,8 @@ declare module '@optimizely/optimizely-sdk' { endOfRange: number; }>; audienceIds: string[]; + // TODO[OASIS-6649]: Don't use object type + // eslint-disable-next-line @typescript-eslint/ban-types forcedVariations: object; } diff --git a/packages/optimizely-sdk/lib/optimizely/index.js b/packages/optimizely-sdk/lib/optimizely/index.js index da7f0412b..f051fd3e1 100644 --- a/packages/optimizely-sdk/lib/optimizely/index.js +++ b/packages/optimizely-sdk/lib/optimizely/index.js @@ -22,11 +22,11 @@ import decisionService from '../core/decision_service'; import enums from '../utils/enums'; import { getImpressionEvent, getConversionEvent } from '../core/event_builder/index.js'; import { buildConversionEvent, buildImpressionEvent } from '../core/event_builder/event_helpers'; -import eventTagsValidator from '../utils/event_tags_validator'; +import * as eventTagsValidator from '../utils/event_tags_validator'; import notificationCenter from '../core/notification_center'; import projectConfig from '../core/project_config'; -import userProfileServiceValidator from '../utils/user_profile_service_validator'; -import stringValidator from '../utils/string_value_validator'; +import * as userProfileServiceValidator from '../utils/user_profile_service_validator'; +import * as stringValidator from '../utils/string_value_validator'; import projectConfigManager from '../core/project_config/project_config_manager'; var ERROR_MESSAGES = enums.ERROR_MESSAGES; diff --git a/packages/optimizely-sdk/lib/optimizely/index.tests.js b/packages/optimizely-sdk/lib/optimizely/index.tests.js index 27bfbfe30..9153fc2a2 100644 --- a/packages/optimizely-sdk/lib/optimizely/index.tests.js +++ b/packages/optimizely-sdk/lib/optimizely/index.tests.js @@ -31,7 +31,7 @@ import errorHandler from '../plugins/error_handler'; import fns from '../utils/fns'; import logger from '../plugins/logger'; import decisionService from '../core/decision_service'; -import jsonSchemaValidator from '../utils/json_schema_validator'; +import * as jsonSchemaValidator from '../utils/json_schema_validator'; import projectConfig from '../core/project_config'; import testData from '../tests/test_data'; diff --git a/packages/optimizely-sdk/lib/utils/attributes_validator/index.tests.js b/packages/optimizely-sdk/lib/utils/attributes_validator/index.tests.js index 96ebbd7f6..91dfaef55 100644 --- a/packages/optimizely-sdk/lib/utils/attributes_validator/index.tests.js +++ b/packages/optimizely-sdk/lib/utils/attributes_validator/index.tests.js @@ -16,7 +16,7 @@ import { assert } from 'chai'; import { sprintf } from '@optimizely/js-sdk-utils'; -import attributesValidator from './'; +import * as attributesValidator from './'; import { ERROR_MESSAGES } from '../enums'; describe('lib/utils/attributes_validator', function() { diff --git a/packages/optimizely-sdk/lib/utils/attributes_validator/index.js b/packages/optimizely-sdk/lib/utils/attributes_validator/index.ts similarity index 76% rename from packages/optimizely-sdk/lib/utils/attributes_validator/index.js rename to packages/optimizely-sdk/lib/utils/attributes_validator/index.ts index 2b15c27a1..8fdccbe50 100644 --- a/packages/optimizely-sdk/lib/utils/attributes_validator/index.js +++ b/packages/optimizely-sdk/lib/utils/attributes_validator/index.ts @@ -18,15 +18,16 @@ import { sprintf } from '@optimizely/js-sdk-utils'; import fns from '../../utils/fns'; import { ERROR_MESSAGES } from '../enums'; -var MODULE_NAME = 'ATTRIBUTES_VALIDATOR'; +const MODULE_NAME = 'ATTRIBUTES_VALIDATOR'; /** * Validates user's provided attributes - * @param {Object} attributes - * @return {boolean} True if the attributes are valid + * @param {unknown} attributes + * @return {boolean} true if the attributes are valid * @throws If the attributes are not valid */ -export var validate = function(attributes) { + +export function validate(attributes: unknown): boolean { if (typeof attributes === 'object' && !Array.isArray(attributes) && attributes !== null) { Object.keys(attributes).forEach(function(key) { if (typeof attributes[key] === 'undefined') { @@ -37,21 +38,19 @@ export var validate = function(attributes) { } else { throw new Error(sprintf(ERROR_MESSAGES.INVALID_ATTRIBUTES, MODULE_NAME)); } -}; +} -export var isAttributeValid = function(attributeKey, attributeValue) { +/** + * Validates user's provided attribute + * @param {unknown} attributeKey + * @param {unknown} attributeValue + * @return {boolean} true if the attribute is valid + */ +export function isAttributeValid(attributeKey: unknown, attributeValue: unknown): boolean { return ( typeof attributeKey === 'string' && (typeof attributeValue === 'string' || typeof attributeValue === 'boolean' || (fns.isNumber(attributeValue) && fns.isSafeInteger(attributeValue))) ); -}; - -/** - * Provides utility method for validating that the attributes user has provided are valid - */ -export default { - validate: validate, - isAttributeValid: isAttributeValid, -}; +} diff --git a/packages/optimizely-sdk/lib/utils/event_tag_utils/index.js b/packages/optimizely-sdk/lib/utils/event_tag_utils/index.js deleted file mode 100644 index 18f8f38cc..000000000 --- a/packages/optimizely-sdk/lib/utils/event_tag_utils/index.js +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright 2017, 2019-2020 Optimizely - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { sprintf } from '@optimizely/js-sdk-utils'; - -import { - LOG_LEVEL, - LOG_MESSAGES, - RESERVED_EVENT_KEYWORDS, -} from '../enums'; - -/** - * Provides utility method for parsing event tag values - */ -var MODULE_NAME = 'EVENT_TAG_UTILS'; -var REVENUE_EVENT_METRIC_NAME = RESERVED_EVENT_KEYWORDS.REVENUE; -var VALUE_EVENT_METRIC_NAME = RESERVED_EVENT_KEYWORDS.VALUE; - -/** - * Grab the revenue value from the event tags. "revenue" is a reserved keyword. - * @param {Object} eventTags - * @param {Object} logger - * @return {Integer|null} - */ -export var getRevenueValue = function(eventTags, logger) { - if (eventTags && eventTags.hasOwnProperty(REVENUE_EVENT_METRIC_NAME)) { - var rawValue = eventTags[REVENUE_EVENT_METRIC_NAME]; - var parsedRevenueValue = parseInt(rawValue, 10); - if (isNaN(parsedRevenueValue)) { - logger.log(LOG_LEVEL.INFO, sprintf(LOG_MESSAGES.FAILED_TO_PARSE_REVENUE, MODULE_NAME, rawValue)); - return null; - } - logger.log(LOG_LEVEL.INFO, sprintf(LOG_MESSAGES.PARSED_REVENUE_VALUE, MODULE_NAME, parsedRevenueValue)); - return parsedRevenueValue; - } - return null; -}; - -/** - * Grab the event value from the event tags. "value" is a reserved keyword. - * @param {Object} eventTags - * @param {Object} logger - * @return {Number|null} - */ -export var getEventValue = function(eventTags, logger) { - if (eventTags && eventTags.hasOwnProperty(VALUE_EVENT_METRIC_NAME)) { - var rawValue = eventTags[VALUE_EVENT_METRIC_NAME]; - var parsedEventValue = parseFloat(rawValue); - if (isNaN(parsedEventValue)) { - logger.log(LOG_LEVEL.INFO, sprintf(LOG_MESSAGES.FAILED_TO_PARSE_VALUE, MODULE_NAME, rawValue)); - return null; - } - logger.log(LOG_LEVEL.INFO, sprintf(LOG_MESSAGES.PARSED_NUMERIC_VALUE, MODULE_NAME, parsedEventValue)); - return parsedEventValue; - } - return null; -}; - -export default { - getRevenueValue: getRevenueValue, - getEventValue: getEventValue, -}; diff --git a/packages/optimizely-sdk/lib/utils/event_tag_utils/index.tests.js b/packages/optimizely-sdk/lib/utils/event_tag_utils/index.tests.js index 7f15f1296..0dc9da982 100644 --- a/packages/optimizely-sdk/lib/utils/event_tag_utils/index.tests.js +++ b/packages/optimizely-sdk/lib/utils/event_tag_utils/index.tests.js @@ -16,7 +16,7 @@ import sinon from 'sinon'; import { assert } from 'chai'; -import eventTagUtils from './'; +import * as eventTagUtils from './'; describe('lib/utils/event_tag_utils', function() { var mockLogger; diff --git a/packages/optimizely-sdk/lib/utils/event_tag_utils/index.ts b/packages/optimizely-sdk/lib/utils/event_tag_utils/index.ts new file mode 100644 index 000000000..56e8528c8 --- /dev/null +++ b/packages/optimizely-sdk/lib/utils/event_tag_utils/index.ts @@ -0,0 +1,90 @@ +/** + * Copyright 2017, 2019-2020 Optimizely + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { sprintf } from '@optimizely/js-sdk-utils'; + +import { EventTags } from '@optimizely/js-sdk-event-processor'; +import { LoggerFacade } from '@optimizely/js-sdk-logging'; + +import { + LOG_LEVEL, + LOG_MESSAGES, + RESERVED_EVENT_KEYWORDS, +} from '../enums'; + +/** + * Provides utility method for parsing event tag values + */ +const MODULE_NAME = 'EVENT_TAG_UTILS'; +const REVENUE_EVENT_METRIC_NAME = RESERVED_EVENT_KEYWORDS.REVENUE; +const VALUE_EVENT_METRIC_NAME = RESERVED_EVENT_KEYWORDS.VALUE; + +/** + * Grab the revenue value from the event tags. "revenue" is a reserved keyword. + * @param {EventTags} eventTags + * @param {LoggerFacade} logger + * @return {number|null} + */ +export function getRevenueValue(eventTags: EventTags, logger: LoggerFacade): number | null { + if (eventTags.hasOwnProperty(REVENUE_EVENT_METRIC_NAME)) { + const rawValue = eventTags[REVENUE_EVENT_METRIC_NAME]; + let parsedRevenueValue; + if (typeof rawValue === 'string') { + parsedRevenueValue = parseInt(rawValue); + if (isNaN(parsedRevenueValue)) { + logger.log(LOG_LEVEL.INFO, sprintf(LOG_MESSAGES.FAILED_TO_PARSE_REVENUE, MODULE_NAME, rawValue)); + return null; + } + logger.log(LOG_LEVEL.INFO, sprintf(LOG_MESSAGES.PARSED_REVENUE_VALUE, MODULE_NAME, parsedRevenueValue)); + return parsedRevenueValue; + } + if (typeof rawValue === 'number') { + parsedRevenueValue = rawValue; + logger.log(LOG_LEVEL.INFO, sprintf(LOG_MESSAGES.PARSED_REVENUE_VALUE, MODULE_NAME, parsedRevenueValue)); + return parsedRevenueValue; + } + return null; + } + return null; +} + +/** + * Grab the event value from the event tags. "value" is a reserved keyword. + * @param {EventTags} eventTags + * @param {LoggerFacade} logger + * @return {number|null} + */ +export function getEventValue(eventTags: EventTags, logger: LoggerFacade): number | null { + if (eventTags.hasOwnProperty(VALUE_EVENT_METRIC_NAME)) { + const rawValue = eventTags[VALUE_EVENT_METRIC_NAME]; + let parsedEventValue; + if (typeof rawValue === 'string') { + parsedEventValue = parseFloat(rawValue); + if (isNaN(parsedEventValue)) { + logger.log(LOG_LEVEL.INFO, sprintf(LOG_MESSAGES.FAILED_TO_PARSE_VALUE, MODULE_NAME, rawValue)); + return null; + } + logger.log(LOG_LEVEL.INFO, sprintf(LOG_MESSAGES.PARSED_NUMERIC_VALUE, MODULE_NAME, parsedEventValue)); + return parsedEventValue; + } + if (typeof rawValue === 'number') { + parsedEventValue = rawValue; + logger.log(LOG_LEVEL.INFO, sprintf(LOG_MESSAGES.PARSED_NUMERIC_VALUE, MODULE_NAME, parsedEventValue)); + return parsedEventValue; + } + return null; + } + return null; +} diff --git a/packages/optimizely-sdk/lib/utils/event_tags_validator/index.js b/packages/optimizely-sdk/lib/utils/event_tags_validator/index.ts similarity index 83% rename from packages/optimizely-sdk/lib/utils/event_tags_validator/index.js rename to packages/optimizely-sdk/lib/utils/event_tags_validator/index.ts index 2d6303d8a..6e97c0fd6 100644 --- a/packages/optimizely-sdk/lib/utils/event_tags_validator/index.js +++ b/packages/optimizely-sdk/lib/utils/event_tags_validator/index.ts @@ -21,22 +21,18 @@ import { sprintf } from '@optimizely/js-sdk-utils'; import { ERROR_MESSAGES } from '../enums'; -var MODULE_NAME = 'EVENT_TAGS_VALIDATOR'; +const MODULE_NAME = 'EVENT_TAGS_VALIDATOR'; /** * Validates user's provided event tags - * @param {Object} event tags - * @return {boolean} True if event tags are valid + * @param {unknown} eventTags + * @return {boolean} true if event tags are valid * @throws If event tags are not valid */ -export var validate = function(eventTags) { +export function validate(eventTags: unknown): boolean { if (typeof eventTags === 'object' && !Array.isArray(eventTags) && eventTags !== null) { return true; } else { throw new Error(sprintf(ERROR_MESSAGES.INVALID_EVENT_TAGS, MODULE_NAME)); } } - -export default { - validate: validate, -} diff --git a/packages/optimizely-sdk/lib/utils/json_schema_validator/index.js b/packages/optimizely-sdk/lib/utils/json_schema_validator/index.ts similarity index 73% rename from packages/optimizely-sdk/lib/utils/json_schema_validator/index.js rename to packages/optimizely-sdk/lib/utils/json_schema_validator/index.ts index 3f21978de..7fa16c05e 100644 --- a/packages/optimizely-sdk/lib/utils/json_schema_validator/index.js +++ b/packages/optimizely-sdk/lib/utils/json_schema_validator/index.ts @@ -17,21 +17,21 @@ import { sprintf } from '@optimizely/js-sdk-utils'; import { validate as jsonSchemaValidator } from 'json-schema'; import { ERROR_MESSAGES } from '../enums'; -import projectConfigSchema from '../../core/project_config/project_config_schema'; +import schema from '../../core/project_config/project_config_schema'; -var MODULE_NAME = 'JSON_SCHEMA_VALIDATOR'; +const MODULE_NAME = 'JSON_SCHEMA_VALIDATOR'; /** * Validate the given json object against the specified schema - * @param {Object} jsonObject The object to validate against the schema - * @return {Boolean} True if the given object is valid + * @param {unknown} jsonObject The object to validate against the schema + * @return {boolean} true if the given object is valid */ -export var validate = function(jsonObject) { - if (!jsonObject) { +export function validate(jsonObject: unknown): boolean { + if (typeof jsonObject !== 'object' || jsonObject === null) { throw new Error(sprintf(ERROR_MESSAGES.NO_JSON_PROVIDED, MODULE_NAME)); } - var result = jsonSchemaValidator(jsonObject, projectConfigSchema); + const result = jsonSchemaValidator(jsonObject, schema); if (result.valid) { return true; } else { @@ -42,8 +42,4 @@ export var validate = function(jsonObject) { } throw new Error(sprintf(ERROR_MESSAGES.INVALID_JSON, MODULE_NAME)); } -}; - -export default { - validate: validate, -}; +} diff --git a/packages/optimizely-sdk/lib/utils/string_value_validator/index.js b/packages/optimizely-sdk/lib/utils/string_value_validator/index.ts similarity index 80% rename from packages/optimizely-sdk/lib/utils/string_value_validator/index.js rename to packages/optimizely-sdk/lib/utils/string_value_validator/index.ts index bde3ed2f9..fd0ceb5f0 100644 --- a/packages/optimizely-sdk/lib/utils/string_value_validator/index.js +++ b/packages/optimizely-sdk/lib/utils/string_value_validator/index.ts @@ -16,13 +16,9 @@ /** * Validates provided value is a non-empty string - * @param {string} input - * @return {boolean} True for non-empty string, false otherwise + * @param {unknown} input + * @return {boolean} true for non-empty string, false otherwise */ -export var validate = function(input) { +export function validate(input: unknown): boolean { return typeof input === 'string' && input !== ''; -}; - -export default { - validate: validate, -}; +} diff --git a/packages/optimizely-sdk/lib/utils/user_profile_service_validator/index.js b/packages/optimizely-sdk/lib/utils/user_profile_service_validator/index.ts similarity index 64% rename from packages/optimizely-sdk/lib/utils/user_profile_service_validator/index.js rename to packages/optimizely-sdk/lib/utils/user_profile_service_validator/index.ts index b8dacb41e..9c264178e 100644 --- a/packages/optimizely-sdk/lib/utils/user_profile_service_validator/index.js +++ b/packages/optimizely-sdk/lib/utils/user_profile_service_validator/index.ts @@ -21,23 +21,24 @@ import { sprintf } from '@optimizely/js-sdk-utils'; import { ERROR_MESSAGES } from '../enums'; -var MODULE_NAME = 'USER_PROFILE_SERVICE_VALIDATOR'; + +const MODULE_NAME = 'USER_PROFILE_SERVICE_VALIDATOR'; /** * Validates user's provided user profile service instance - * @param {Object} userProfileServiceInstance - * @return {boolean} True if the instance is valid + * @param {unknown} userProfileServiceInstance + * @return {boolean} true if the instance is valid * @throws If the instance is not valid */ -export var validate = function(userProfileServiceInstance) { - if (typeof userProfileServiceInstance.lookup !== 'function') { - throw new Error(sprintf(ERROR_MESSAGES.INVALID_USER_PROFILE_SERVICE, MODULE_NAME, "Missing function 'lookup'")); - } else if (typeof userProfileServiceInstance.save !== 'function') { - throw new Error(sprintf(ERROR_MESSAGES.INVALID_USER_PROFILE_SERVICE, MODULE_NAME, "Missing function 'save'")); - } - return true; -}; -export default { - validate: validate, -}; +export function validate(userProfileServiceInstance: unknown): boolean { + if (typeof userProfileServiceInstance === 'object' && userProfileServiceInstance !== null) { + if (typeof userProfileServiceInstance['lookup'] !== 'function') { + throw new Error(sprintf(ERROR_MESSAGES.INVALID_USER_PROFILE_SERVICE, MODULE_NAME, "Missing function 'lookup'")); + } else if (typeof userProfileServiceInstance['save'] !== 'function') { + throw new Error(sprintf(ERROR_MESSAGES.INVALID_USER_PROFILE_SERVICE, MODULE_NAME, "Missing function 'save'")); + } + return true; + } + throw new Error(sprintf(ERROR_MESSAGES.INVALID_USER_PROFILE_SERVICE, MODULE_NAME)); +} diff --git a/packages/optimizely-sdk/package-lock.json b/packages/optimizely-sdk/package-lock.json index eeae8828d..f98d30950 100644 --- a/packages/optimizely-sdk/package-lock.json +++ b/packages/optimizely-sdk/package-lock.json @@ -496,18 +496,42 @@ } } }, + "@types/chai": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz", + "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==", + "dev": true + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, "@types/estree": { "version": "0.0.39", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==", "dev": true }, + "@types/json-schema": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", + "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", + "dev": true + }, + "@types/mocha": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", + "dev": true + }, "@types/node": { "version": "13.11.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-13.11.0.tgz", @@ -523,6 +547,120 @@ "@types/node": "*" } }, + "@typescript-eslint/eslint-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.2.0.tgz", + "integrity": "sha512-t9RTk/GyYilIXt6BmZurhBzuMT9kLKw3fQoJtK9ayv0tXTlznXEAnx07sCLXdkN3/tZDep1s1CEV95CWuARYWA==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "3.2.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.2.0.tgz", + "integrity": "sha512-UbJBsk+xO9dIFKtj16+m42EvUvsjZbbgQ2O5xSTSfVT1Z3yGkL90DVu0Hd3029FZ5/uBgl+F3Vo8FAcEcqc6aQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "3.2.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.2.0.tgz", + "integrity": "sha512-Vhu+wwdevDLVDjK1lIcoD6ZbuOa93fzqszkaO3iCnmrScmKwyW/AGkzc2UvfE5TCoCXqq7Jyt6SOXjsIlpqF4A==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "3.2.0", + "@typescript-eslint/typescript-estree": "3.2.0", + "eslint-visitor-keys": "^1.1.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.2.0.tgz", + "integrity": "sha512-uh+Y2QO7dxNrdLw7mVnjUqkwO/InxEqwN0wF+Za6eo3coxls9aH9kQ/5rSvW2GcNanebRTmsT5w1/92lAOb1bA==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } + } + }, "@webassemblyjs/ast": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", @@ -870,6 +1008,12 @@ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -2609,12 +2753,6 @@ "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", "dev": true }, - "esm": { - "version": "3.2.25", - "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", - "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", - "dev": true - }, "espree": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", @@ -5090,6 +5228,12 @@ } } }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -6407,6 +6551,122 @@ "terser": "^4.6.2" } }, + "rollup-plugin-typescript2": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.27.1.tgz", + "integrity": "sha512-RJl77Bbj1EunAQDC3dK/O2HWuSUX3oJbRGzyLoS5o9W4Hs1Nix3Gavqj1Lzs5Y6Ff4H2xXfmZ1WWUQCYocSbzQ==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^3.0.8", + "find-cache-dir": "^3.3.1", + "fs-extra": "8.1.0", + "resolve": "1.15.1", + "tslib": "1.11.2" + }, + "dependencies": { + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "tslib": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.2.tgz", + "integrity": "sha512-tTSkux6IGPnUGUd1XAZHcpu85MOkIl5zX49pO+jfsie3eP0B6pyhOlLXm3cAC6T7s+euSDDUUV+Acop5WmtkVg==", + "dev": true + } + } + }, "rollup-pluginutils": { "version": "2.8.2", "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", @@ -7458,12 +7718,122 @@ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "dev": true }, + "ts-loader": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-7.0.5.tgz", + "integrity": "sha512-zXypEIT6k3oTc+OZNx/cqElrsbBtYqDknf48OZos0NQ3RTt045fBIU8RRSu+suObBzYB355aIPGOe/3kj9h7Ig==", + "dev": true, + "requires": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^4.0.0", + "semver": "^6.0.0" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "ts-node": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + } + } + }, "tslib": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", "dev": true }, + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", @@ -7549,6 +7919,12 @@ "is-typedarray": "^1.0.0" } }, + "typescript": { + "version": "3.3.3333", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.3333.tgz", + "integrity": "sha512-JjSKsAfuHBE/fB2oZ8NxtRTk5iGcg6hkYXMnZ3Wc+b2RSqejEqTaem11mHASMnFilHrax3sLK0GDzcJrekZYLw==", + "dev": true + }, "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", @@ -8083,6 +8459,12 @@ "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", "dev": true + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true } } } diff --git a/packages/optimizely-sdk/package.json b/packages/optimizely-sdk/package.json index a982fa845..ba154513e 100644 --- a/packages/optimizely-sdk/package.json +++ b/packages/optimizely-sdk/package.json @@ -9,8 +9,8 @@ "typings": "lib/index.d.ts", "scripts": { "clean": "rm -rf dist", - "lint": "eslint 'lib/**/*.js'", - "test": "mocha -r esm -r lib/tests/exit_on_unhandled_rejection.js 'lib/**/*.tests.js'", + "lint": "tsc --noEmit && eslint 'lib/**/*.js' 'lib/**/*.ts'", + "test": "TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha -r ts-node/register -r lib/tests/exit_on_unhandled_rejection.js 'lib/**/*.tests.ts' 'lib/**/*.tests.js'", "posttest": "npm run lint", "test-ci": "npm run test-xbrowser && npm run test-umdbrowser", "test-xbrowser": "karma start karma.bs.conf.js --single-run", @@ -51,11 +51,14 @@ "devDependencies": { "@rollup/plugin-commonjs": "^11.0.2", "@rollup/plugin-node-resolve": "^7.1.1", + "@types/chai": "^4.2.11", + "@types/mocha": "^5.2.7", + "@typescript-eslint/eslint-plugin": "^3.2.0", + "@typescript-eslint/parser": "^3.2.0", "bluebird": "^3.4.6", "chai": "^4.2.0", "coveralls": "^3.0.2", "eslint": "^6.7.2", - "esm": "^3.2.25", "json-loader": "^0.5.4", "karma": "^4.4.1", "karma-browserstack-launcher": "^1.5.1", @@ -71,7 +74,11 @@ "promise-polyfill": "8.1.0", "rollup": "2.2.0", "rollup-plugin-terser": "^5.3.0", + "rollup-plugin-typescript2": "^0.27.1", "sinon": "^2.3.1", + "ts-loader": "^7.0.5", + "ts-node": "^8.10.2", + "typescript": "^3.3.3333", "webpack": "^4.42.1" }, "publishConfig": { diff --git a/packages/optimizely-sdk/rollup.config.js b/packages/optimizely-sdk/rollup.config.js index 129bdbc51..aec65ce46 100644 --- a/packages/optimizely-sdk/rollup.config.js +++ b/packages/optimizely-sdk/rollup.config.js @@ -18,9 +18,30 @@ import commonjs from '@rollup/plugin-commonjs'; import { terser } from 'rollup-plugin-terser'; import resolve from '@rollup/plugin-node-resolve'; import { dependencies } from './package.json'; +import typescript from 'rollup-plugin-typescript2'; + +const typescriptPluginOptions = { + allowJs: true, + exclude: [ + './dist', + './lib/**/*.tests.js', + './lib/**/*.tests.ts', + './lib/**/*.umdtests.js', + './lib/tests', + 'node_modules' + ], + include: [ + './lib/**/*.ts', + './lib/**/*.js' + ], +}; const cjsBundleFor = (platform) => ({ - plugins: [resolve(), commonjs()], + plugins: [ + resolve(), + commonjs(), + typescript(typescriptPluginOptions), + ], external: ['https', 'http', 'url'].concat(Object.keys(dependencies || {})), input: `lib/index.${platform}.js`, output: { @@ -66,6 +87,7 @@ const umdBundle = { '@optimizely/js-sdk-event-processor': ['LogTierV1EventProcessor', 'LocalStoragePendingEventsDispatcher'], }, }), + typescript(typescriptPluginOptions), ], input: 'lib/index.browser.js', output: [ @@ -88,9 +110,13 @@ const umdBundle = { // A separate bundle for json schema validator. const jsonSchemaBundle = { - plugins: [resolve(), commonjs()], + plugins: [ + resolve(), + commonjs(), + typescript(typescriptPluginOptions), + ], external: ['json-schema', '@optimizely/js-sdk-utils'], - input: 'lib/utils/json_schema_validator/index.js', + input: 'lib/utils/json_schema_validator/index.ts', output: { exports: 'named', format: 'cjs', diff --git a/packages/optimizely-sdk/tsconfig.json b/packages/optimizely-sdk/tsconfig.json new file mode 100644 index 000000000..250ef5bea --- /dev/null +++ b/packages/optimizely-sdk/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "allowJs": true, + "declaration": false, + "module": "esnext", + "outDir": "./dist", + "sourceMap": true + }, + "exclude": [ + "./dist", + "./lib/**/*.tests.js", + "./lib/**/*.tests.ts", + "./lib/**/*.umdtests.js", + "./lib/tests", + "node_modules" + ], + "include": [ + "./lib/**/*.ts", + "./lib/**/*.js" + ] + }