New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@cashstar/react-timezone

Package Overview
Dependencies
Maintainers
2
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cashstar/react-timezone - npm Package Compare versions

Comparing version 2.0.1 to 2.0.2

_gh-pages/favicon.ico

26

lib/utils/search.js

@@ -7,10 +7,10 @@ 'use strict';

/**
* True or false as to whether the input value is contained within the string.
* @param {string} input
* True or false as to whether the search value is contained within the string.
* @param {string} searchValue
* @param {string} string
* @return {boolean}
*/
var isMatch = function isMatch(input, string) {
if (!input || !string || typeof input !== 'string' || typeof string !== 'string') return false;
var valueToSearchFor = input.toLowerCase();
var isMatch = function isMatch(searchValue, string) {
if (!searchValue || !string || typeof searchValue !== 'string' || typeof string !== 'string') return false;
var valueToSearchFor = searchValue.toLowerCase();
var stringToSearchIn = string.toLowerCase();

@@ -25,3 +25,3 @@

* @param {string|Object} item - the item to search within
* @param {string} text - the text to search for in the item
* @param {string} searchValue - the text to search for in the item
* @param {Object} filterOptions - options used for filtering which include:

@@ -32,13 +32,13 @@ * {Array} fields - the fields to use to search against on the item

*/
var filterBy = function filterBy(item, text, filterOptions) {
var filterBy = function filterBy(item, searchValue, filterOptions) {
var fields = filterOptions.fields.slice();
var minLength = filterOptions.minLength || 1;
if (text.length < minLength) return false;
if (searchValue.length < minLength) return false;
if (fields.length) {
return fields.some(function (field) {
var value = item[field];
var sectionToSearch = item[field];
if (typeof value !== 'string') {
if (typeof sectionToSearch !== 'string') {
console.warn( // eslint-disable-line

@@ -48,10 +48,10 @@ false, 'Fields passed to \'filterBy\' should have string values. Value will be converted to a string; results may be unexpected.');

// Coerce to string since `toString` isn't null-safe.
value += '';
sectionToSearch += '';
}
return isMatch(text, value);
return isMatch(searchValue, sectionToSearch);
});
}
return isMatch(text, item);
return isMatch(searchValue, item);
};

@@ -58,0 +58,0 @@

@@ -7,2 +7,4 @@ 'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _momentTimezone = require('moment-timezone');

@@ -50,5 +52,5 @@

// see https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent#Mobile_Tablet_or_Desktop
var isMobile = global.navigator !== undefined ? global.navigator.userAgent.match(/Mobi/) : false;
var isMobile = typeof window.navigator !== 'undefined' ? !!window.navigator.userAgent.match(/Mobi/) : false;
var supportsIntl = global.Intl !== undefined;
var supportsIntl = window.Intl && _typeof(window.Intl) === 'object';

@@ -59,10 +61,19 @@ var userTz = void 0;

// moment-timezone gives preference to the Intl API regardless of device type,
// so unset global.Intl to trick moment-timezone into using its fallback
// so unset window.Intl.DateTimeFormat().resolvedOptions() to trick moment-timezone into using its fallback
// see https://github.com/moment/moment-timezone/issues/441 and
// see https://github.com/moment/moment-timezone/issues/517
// TODO: Clean this up when that issue is resolved
var globalIntl = global.Intl;
global.Intl = undefined;
var originalDateTimeFormat = window.Intl.DateTimeFormat;
window.Intl.DateTimeFormat = function newDateTimeFormat() {
return {
resolvedOptions: function resolvedOptions() {
return {};
}
};
};
userTz = _momentTimezone2.default.tz.guess();
global.Intl = globalIntl;
window.Intl.DateTimeFormat = originalDateTimeFormat;
} else {

@@ -69,0 +80,0 @@ userTz = _momentTimezone2.default.tz.guess();

{
"name": "@cashstar/react-timezone",
"version": "2.0.1",
"version": "2.0.2",
"description": "A timezone picker widget in React",

@@ -19,2 +19,6 @@ "main": "index.js",

"storybook": "start-storybook -p 9001 -c .storybook",
"gh-pages:clean": "rimraf _gh-pages",
"gh-pages:build": "$(npm bin)/build-storybook -o _gh-pages",
"gh-pages:publish": "$(npm bin)/git-directory-deploy --directory _gh-pages",
"gh-pages": "npm run gh-pages:clean && npm run gh-pages:build && npm run gh-pages:publish",
"tag": "git tag v$npm_package_version",

@@ -26,3 +30,4 @@ "version:patch": "npm --no-git-tag-version version patch",

"postversion": "git commit package.json -m \"Version $npm_package_version\" && npm run tag && git push && git push --tags && npm publish --registry=https://registry.npmjs.org/",
"prepublish": "npm run build"
"prepublish": "npm run build",
"postpublish": "npm run gh-pages"
},

@@ -45,2 +50,3 @@ "repository": {

"coveralls": "^3.0.0",
"git-directory-deploy": "^1.5.1",
"invariant": "^2.2.2",

@@ -47,0 +53,0 @@ "react-autocomplete": "^1.7.2"

@@ -1,10 +0,20 @@

[![Build Status](https://travis-ci.org/erin-doyle/react-timezone.svg?branch=master)](https://travis-ci.org/erin-doyle/react-timezone)
# react-timezone <sup>[![Version Badge][npm-version-svg]][package-url]</sup>
[![Coverage Status](https://coveralls.io/repos/github/erin-doyle/react-timezone/badge.svg)](https://coveralls.io/github/erin-doyle/react-timezone)
[![Build Status][travis-svg]][travis-url]
[![Coverage status][coveralls-svg]][coveralls-url]
[![Downloads][downloads-image]][downloads-url]
# react-timezone
Timezone picker widget using React
[![npm badge][npm-badge-png]][package-url]
> Timezone picker widget using React.
_TODO: add gif of TimezoneAutocomplete in action_
## Getting Started

@@ -291,2 +301,12 @@ ### Local Demo

// 0
```
```
[package-url]: https://npmjs.org/package/@cashstar/react-timezone
[npm-version-svg]: http://versionbadg.es/erin-doyle/react-timezone.svg
[travis-svg]: https://travis-ci.org/erin-doyle/react-timezone.svg?branch=master
[travis-url]: https://travis-ci.org/erin-doyle/react-timezone
[coveralls-svg]: https://coveralls.io/repos/github/erin-doyle/react-timezone/badge.svg
[coveralls-url]: https://coveralls.io/github/erin-doyle/react-timezone
[npm-badge-png]: https://nodei.co/npm/@cashstar/react-timezone.png?downloads=true&stars=true
[downloads-image]: http://img.shields.io/npm/dm/@cashstar/react-timezone.svg
[downloads-url]: http://npm-stat.com/charts.html?package=@cashstar/react-timezone
/**
* True or false as to whether the input value is contained within the string.
* @param {string} input
* True or false as to whether the search value is contained within the string.
* @param {string} searchValue
* @param {string} string
* @return {boolean}
*/
const isMatch = (input, string) => {
if (!input || !string || typeof input !== 'string' || typeof string !== 'string') return false;
const valueToSearchFor = input.toLowerCase();
const isMatch = (searchValue, string) => {
if (!searchValue || !string || typeof searchValue !== 'string' || typeof string !== 'string') return false;
const valueToSearchFor = searchValue.toLowerCase();
const stringToSearchIn = string.toLowerCase();

@@ -19,3 +19,3 @@

* @param {string|Object} item - the item to search within
* @param {string} text - the text to search for in the item
* @param {string} searchValue - the text to search for in the item
* @param {Object} filterOptions - options used for filtering which include:

@@ -26,13 +26,13 @@ * {Array} fields - the fields to use to search against on the item

*/
const filterBy = (item, text, filterOptions) => {
const filterBy = (item, searchValue, filterOptions) => {
const fields = filterOptions.fields.slice();
const minLength = filterOptions.minLength || 1;
if (text.length < minLength) return false;
if (searchValue.length < minLength) return false;
if (fields.length) {
return fields.some((field) => {
let value = item[field];
let sectionToSearch = item[field];
if (typeof value !== 'string') {
if (typeof sectionToSearch !== 'string') {
console.warn( // eslint-disable-line

@@ -45,10 +45,10 @@ false,

// Coerce to string since `toString` isn't null-safe.
value += '';
sectionToSearch += '';
}
return isMatch(text, value);
return isMatch(searchValue, sectionToSearch);
});
}
return isMatch(text, item);
return isMatch(searchValue, item);
};

@@ -55,0 +55,0 @@

@@ -33,7 +33,7 @@ import moment from 'moment-timezone';

// see https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent#Mobile_Tablet_or_Desktop
const isMobile = global.navigator !== undefined
? global.navigator.userAgent.match(/Mobi/)
const isMobile = typeof window.navigator !== 'undefined'
? !!window.navigator.userAgent.match(/Mobi/)
: false;
const supportsIntl = global.Intl !== undefined;
const supportsIntl = window.Intl && typeof window.Intl === 'object';

@@ -44,10 +44,17 @@ let userTz;

// moment-timezone gives preference to the Intl API regardless of device type,
// so unset global.Intl to trick moment-timezone into using its fallback
// so unset window.Intl.DateTimeFormat().resolvedOptions() to trick moment-timezone into using its fallback
// see https://github.com/moment/moment-timezone/issues/441 and
// see https://github.com/moment/moment-timezone/issues/517
// TODO: Clean this up when that issue is resolved
const globalIntl = global.Intl;
global.Intl = undefined;
const originalDateTimeFormat = window.Intl.DateTimeFormat;
window.Intl.DateTimeFormat = function newDateTimeFormat() {
return {
resolvedOptions() { return {}; }
};
};
userTz = moment.tz.guess();
global.Intl = globalIntl;
window.Intl.DateTimeFormat = originalDateTimeFormat;
} else {

@@ -54,0 +61,0 @@ userTz = moment.tz.guess();

/* eslint-disable max-len */ // lots of long test names and that's ok
import { tz as momentTimezone } from 'moment-timezone';
import timeHelper from '../../src/utils/time';

@@ -10,88 +12,256 @@ import { EASTERN_TZ } from '../testUtils';

};
const newYorkTimezone = {
city: 'New York',
zoneAbbr: EASTERN_TZ,
zoneName: 'America/New_York'
};
const greenwhichTimezone = {
city: 'Greenwich',
zoneAbbr: 'GMT',
zoneName: 'Etc/Greenwich'
};
const mockMobileUserAgent = 'Mozilla/5.0 (Linux; Android 4.4.2; GT-I9515L Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36';
const mockDesktopUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36';
describe('Time utils', () => {
describe('tzSearch with city argument', () => {
it('should return an array of one timezone object containing the provided city', () => {
const cityToSearchFor = 'New York';
const result = timeHelper.tzSearch({ city: cityToSearchFor });
expect(result).toHaveLength(1);
expect(result[0].city).toEqual(cityToSearchFor);
});
describe('tzSearch', () => {
describe('with city argument', () => {
it('should return an array of one timezone object containing the provided city', () => {
const cityToSearchFor = 'New York';
const result = timeHelper.tzSearch({ city: cityToSearchFor });
expect(result).toHaveLength(1);
expect(result[0].city).toEqual(cityToSearchFor);
});
it('should return an empty array when a timezone object does not exist containing the provided city', () => {
const cityToSearchFor = 'Some City that should not exist in the Timezone data';
const result = timeHelper.tzSearch({ city: cityToSearchFor });
expect(result).toHaveLength(0);
it('should return an empty array when a timezone object does not exist containing the provided city', () => {
const cityToSearchFor = 'Some City that should not exist in the Timezone data';
const result = timeHelper.tzSearch({ city: cityToSearchFor });
expect(result).toHaveLength(0);
});
});
});
describe('tzSearch with name argument', () => {
it('should return the first timezone object containing the provided name', () => {
const nameToSearchFor = 'America/New_York';
const result = timeHelper.tzSearch({ zoneName: nameToSearchFor });
expect(result).toHaveLength(1);
expect(result[0].zoneName).toEqual(nameToSearchFor);
describe('with name argument', () => {
it('should return the first timezone object containing the provided name', () => {
const nameToSearchFor = 'America/New_York';
const result = timeHelper.tzSearch({ zoneName: nameToSearchFor });
expect(result).toHaveLength(1);
expect(result[0].zoneName).toEqual(nameToSearchFor);
});
it('should return an empty array when a timezone object does not exist containing the provided name', () => {
const nameToSearchFor = 'Some Name that should not exist in the Timezone data';
const result = timeHelper.tzSearch({ zoneName: nameToSearchFor });
expect(result).toHaveLength(0);
});
});
it('should return an empty array when a timezone object does not exist containing the provided name', () => {
const nameToSearchFor = 'Some Name that should not exist in the Timezone data';
const result = timeHelper.tzSearch({ zoneName: nameToSearchFor });
expect(result).toHaveLength(0);
describe('with city and abbr arguments', () => {
it('should return the matching timezone object containing the provided city and zone abbreviation', () => {
const cityToSearchFor = 'New';
const zoneToSearchFor = EASTERN_TZ;
const result = timeHelper.tzSearch({ city: cityToSearchFor, zoneAbbr: zoneToSearchFor });
expect(result).toHaveLength(1);
expect(result[0].city).toContain(cityToSearchFor);
expect(result[0].zoneAbbr).toContain(zoneToSearchFor);
});
it('should return an empty array when a timezone object does not exist containing the provided city and zone abbreviation', () => {
const cityToSearchFor = 'Some City that should not exist in the Timezone data';
const zoneToSearchFor = 'ABCDEFG';
const result = timeHelper.tzSearch({ city: cityToSearchFor, zoneAbbr: zoneToSearchFor });
expect(result).toHaveLength(0);
});
});
});
describe('tzSearch with city and abbr arguments', () => {
it('should return the matching timezone object containing the provided city and zone abbreviation', () => {
const cityToSearchFor = 'New';
const zoneToSearchFor = EASTERN_TZ;
const result = timeHelper.tzSearch({ city: cityToSearchFor, zoneAbbr: zoneToSearchFor });
expect(result).toHaveLength(1);
expect(result[0].city).toContain(cityToSearchFor);
expect(result[0].zoneAbbr).toContain(zoneToSearchFor);
describe('with city and name arguments', () => {
it('should return the matching timezone object containing the provided city and zone name', () => {
const cityToSearchFor = 'New';
const zoneToSearchFor = 'America';
const result = timeHelper.tzSearch({ city: cityToSearchFor, zoneName: zoneToSearchFor });
expect(result).toHaveLength(2);
expect(result[0].city).toContain(cityToSearchFor);
expect(result[0].zoneName).toContain(zoneToSearchFor);
});
it('should return an empty array when a timezone object does not exist containing the provided city and zone name', () => {
const cityToSearchFor = 'Some City that should not exist in the Timezone data';
const zoneToSearchFor = 'ABCDEFG';
const result = timeHelper.tzSearch({ city: cityToSearchFor, zoneName: zoneToSearchFor });
expect(result).toHaveLength(0);
});
});
it('should return an empty array when a timezone object does not exist containing the provided city and zone abbreviation', () => {
const cityToSearchFor = 'Some City that should not exist in the Timezone data';
const zoneToSearchFor = 'ABCDEFG';
const result = timeHelper.tzSearch({ city: cityToSearchFor, zoneAbbr: zoneToSearchFor });
expect(result).toHaveLength(0);
describe('with filterFields that do not exist', () => {
it('should return an empty array if passed only filterFields that do not exist on the timezone object', () => {
const result = timeHelper.tzSearch({
fieldOneThatDoesntExist: 'someValue',
fieldTwoThatDoesntExist: 'someOtherValue'
});
expect(result).toHaveLength(0);
});
it('should return an empty array if passed any filterFields that do not exist on the timezone object along with any that do exist', () => {
const cityToSearchFor = 'New York';
const zoneToSearchFor = 'EDT';
const result = timeHelper.tzSearch({
fieldOneThatDoesntExist: 'someValue',
city: cityToSearchFor,
zoneAbbr: zoneToSearchFor
});
expect(result).toHaveLength(0);
});
});
});
describe('tzSearch with city and name arguments', () => {
it('should return the matching timezone object containing the provided city and zone name', () => {
const cityToSearchFor = 'New';
const zoneToSearchFor = 'America';
const result = timeHelper.tzSearch({ city: cityToSearchFor, zoneName: zoneToSearchFor });
expect(result).toHaveLength(2);
expect(result[0].city).toContain(cityToSearchFor);
expect(result[0].zoneName).toContain(zoneToSearchFor);
describe('guessUserTz', () => {
afterEach(() => {
jest.resetAllMocks();
});
it('should return an empty array when a timezone object does not exist containing the provided city and zone name', () => {
const cityToSearchFor = 'Some City that should not exist in the Timezone data';
const zoneToSearchFor = 'ABCDEFG';
const result = timeHelper.tzSearch({ city: cityToSearchFor, zoneName: zoneToSearchFor });
expect(result).toHaveLength(0);
describe('when the device is mobile and Intl is supported', () => {
const originalIntl = window.Intl;
const mockResolvedOptions = jest.fn();
beforeEach(() => {
window.navigator.userAgent = mockMobileUserAgent;
window.Intl.DateTimeFormat = jest.fn().mockImplementation(
() => {
resolvedOptions: mockResolvedOptions
}
);
});
afterAll(() => {
window.Intl = originalIntl;
});
describe('when the user timezone is found', () => {
let guessedTimezone;
beforeEach(() => {
jest.spyOn(momentTimezone, 'guess').mockImplementation(() => newYorkTimezone.zoneName);
guessedTimezone = timeHelper.guessUserTz();
});
it('returns the user timezone', () => {
expect(guessedTimezone).toEqual(newYorkTimezone);
});
it('does not call window.Intl.DateTimeFormat().resolvedOptions()', () => {
expect(mockResolvedOptions).not.toHaveBeenCalled();
});
});
describe('when the user timezone is not found', () => {
let guessedTimezone;
beforeEach(() => {
jest.spyOn(momentTimezone, 'guess').mockImplementation(() => undefined);
guessedTimezone = timeHelper.guessUserTz();
});
it('returns the GMT timezone', () => {
expect(guessedTimezone).toEqual(greenwhichTimezone);
});
it('does not call window.Intl.DateTimeFormat().resolvedOptions()', () => {
expect(mockResolvedOptions).not.toHaveBeenCalled();
});
});
describe('when the user timezone is UTC', () => {
let guessedTimezone;
beforeEach(() => {
jest.spyOn(momentTimezone, 'guess').mockImplementation(() => 'UTC');
guessedTimezone = timeHelper.guessUserTz();
});
it('returns the GMT timezone', () => {
expect(guessedTimezone).toEqual(greenwhichTimezone);
});
it('does not call window.Intl.DateTimeFormat().resolvedOptions()', () => {
expect(mockResolvedOptions).not.toHaveBeenCalled();
});
});
});
});
describe('tzSearch with filterFields that do not exist', () => {
it('should return an empty array if passed only filterFields that do not exist on the timezone object', () => {
const result = timeHelper.tzSearch({
fieldOneThatDoesntExist: 'someValue',
fieldTwoThatDoesntExist: 'someOtherValue'
describe('when the device is mobile and Intl is not supported', () => {
const originalIntl = window.Intl;
beforeEach(() => {
window.navigator.userAgent = mockMobileUserAgent;
window.Intl = undefined;
});
expect(result).toHaveLength(0);
afterAll(() => {
window.Intl = originalIntl;
});
describe('when the user timezone is found', () => {
beforeEach(() => {
jest.spyOn(momentTimezone, 'guess').mockImplementation(() => newYorkTimezone.zoneName);
});
it('returns the user timezone', () => {
expect(timeHelper.guessUserTz()).toEqual(newYorkTimezone);
});
});
describe('when the user timezone is not found', () => {
beforeEach(() => {
jest.spyOn(momentTimezone, 'guess').mockImplementation(() => undefined);
});
it('returns the GMT timezone', () => {
expect(timeHelper.guessUserTz()).toEqual(greenwhichTimezone);
});
});
describe('when the user timezone is UTC', () => {
beforeEach(() => {
jest.spyOn(momentTimezone, 'guess').mockImplementation(() => 'UTC');
});
it('returns the GMT timezone', () => {
expect(timeHelper.guessUserTz()).toEqual(greenwhichTimezone);
});
});
});
it('should return an empty array if passed any filterFields that do not exist on the timezone object along with any that do exist', () => {
const cityToSearchFor = 'New York';
const zoneToSearchFor = 'EDT';
const result = timeHelper.tzSearch({
fieldOneThatDoesntExist: 'someValue',
city: cityToSearchFor,
zoneAbbr: zoneToSearchFor
describe('when the device is not mobile', () => {
beforeEach(() => {
window.navigator.userAgent = mockDesktopUserAgent;
});
expect(result).toHaveLength(0);
describe('when the user timezone is found', () => {
beforeEach(() => {
jest.spyOn(momentTimezone, 'guess').mockImplementation(() => newYorkTimezone.zoneName);
});
it('returns the user timezone', () => {
expect(timeHelper.guessUserTz()).toEqual(newYorkTimezone);
});
});
describe('when the user timezone is not found', () => {
beforeEach(() => {
jest.spyOn(momentTimezone, 'guess').mockImplementation(() => undefined);
});
it('returns the GMT timezone', () => {
expect(timeHelper.guessUserTz()).toEqual(greenwhichTimezone);
});
});
describe('when the user timezone is UTC', () => {
beforeEach(() => {
jest.spyOn(momentTimezone, 'guess').mockImplementation(() => 'UTC');
});
it('returns the GMT timezone', () => {
expect(timeHelper.guessUserTz()).toEqual(greenwhichTimezone);
});
});
});

@@ -98,0 +268,0 @@ });

@@ -5,1 +5,14 @@ import { configure } from 'enzyme';

configure({ adapter: new Adapter() });
// This allows us to fake the userAgent string for testing
Object.defineProperty(window.navigator, 'userAgent', (
function userAgent(_value) {
return {
get: function _get() {
return _value;
},
set: function _set(val) {
_value = val; // eslint-disable-line no-param-reassign
}
};
}(window.navigator.userAgent)));

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
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc