@becollective/utils 1.7.1 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,44 @@
1
+ version: v1.0
2
+ name: @becollective/utils
3
+ agent:
4
+ machine:
5
+ type: e1-standard-2
6
+ os_image: ubuntu2004
7
+ blocks:
8
+ - name: Test
9
+ task:
10
+ secrets:
11
+ - name: NPM
12
+ - name: BUILD_DEPRECATED
13
+ prologue:
14
+ commands:
15
+ - checkout
16
+ - export AWS_ACCESS_KEY_ID=$AWS_BUILD_DEPRECATED_ACCESS_KEY
17
+ - export AWS_SECRET_ACCESS_KEY=$AWS_BUILD_DEPRECATED_SECRET_ACCESS_KEY
18
+ jobs:
19
+ - name: Test
20
+ commands:
21
+ - cd ./packages/utils
22
+ - npm ci
23
+ - npm run test
24
+ - name: Publish
25
+ skip:
26
+ when: "branch != 'master'"
27
+ task:
28
+ secrets:
29
+ - name: NPM
30
+ - name: BUILD_DEPRECATED
31
+ env_vars:
32
+ - name: PACKAGE_DIR
33
+ value: ./packages/utils
34
+ prologue:
35
+ commands:
36
+ - checkout
37
+ - export AWS_ACCESS_KEY_ID=$AWS_BUILD_DEPRECATED_ACCESS_KEY
38
+ - export AWS_SECRET_ACCESS_KEY=$AWS_BUILD_DEPRECATED_SECRET_ACCESS_KEY
39
+ jobs:
40
+ - name: Publish
41
+ commands:
42
+ - echo "deploying @becollective/utils"
43
+ - sh ./.semaphore/deployer.sh
44
+
package/README.md ADDED
@@ -0,0 +1,149 @@
1
+ # @becollective/utils
2
+
3
+ ## Description
4
+
5
+ ---
6
+
7
+ A collection of helper methods for handling regional issues, feature-flags and password checking functionality.
8
+
9
+ These include:
10
+
11
+ - Age, underSixteen and date diff checks
12
+ - Turns shift dates into readable text
13
+ - Fetch feature-flags from feature flag service
14
+ - Get a tagged home location from a list of locations
15
+ - Money formatting strings
16
+ - Password checks
17
+
18
+ ## :computer: Pre-requisites
19
+
20
+ ---
21
+
22
+ Some projects have different node versions I would recommend using:
23
+ [nvm](https://github.com/nvm-sh/nvm/blob/master/README.md)
24
+
25
+ node version for api: `node:14-alpine`
26
+
27
+ Ensure you have done the following in the [confluence](https://becollective.atlassian.net/wiki/spaces/ENGINEERIN/pages/1605849/Setup+Local+Development+Environment) link
28
+
29
+ - `Setup Local Development Environment`
30
+
31
+ - `Dependency services for local Be Collective Services`
32
+
33
+ ## :wave: Getting started
34
+
35
+ ---
36
+
37
+ - Clone the repository
38
+
39
+ ```
40
+ git clone <https://github.com/tickboxAU/becollective-npm.git>
41
+ ```
42
+
43
+ ```
44
+ cd becollective-npm
45
+ ```
46
+
47
+ ```
48
+ cd packages/utils
49
+ ```
50
+
51
+ ```
52
+ bcDocker
53
+ ```
54
+
55
+ - `bcDocker` [confluence](https://becollective.atlassian.net/wiki/spaces/ENGINEERIN/pages/1605849/1+-+Setup+Local+Development+Environment#Dependency-services-for-local-Be-Collective-Services)
56
+
57
+ - Install dependencies
58
+
59
+ ```
60
+ npm install
61
+ ```
62
+
63
+ - how to run tests
64
+
65
+ ```
66
+ npm run test
67
+ ```
68
+
69
+ - how to build
70
+
71
+ ```
72
+ npm run build
73
+ ```
74
+
75
+ ## Project Structure
76
+
77
+ ---
78
+
79
+ The folder structure of this project is explained below:
80
+
81
+ | Name | Description |
82
+ | ----------------------- | -------------------------------------------------- |
83
+ | **node_modules** | Contains all npm dependencies |
84
+ | **.semaphore** | Contains the deployment yml for semaphore |
85
+ | **src/date-time** | Date-time helper methods |
86
+ | **src/FeatureFlag** | Feature flag helper methods |
87
+ | **src/locality** | Location helper methods |
88
+ | **src/money** | Money string helper methods |
89
+ | **src/opportunity** | Opportunity types |
90
+ | **src/opportunityUser** | Opportunity time helper methods |
91
+ | **src/password** | Password validation helper methods |
92
+ | **tests** | Contain all tests |
93
+ | **jestconfig.js** | Test configuration |
94
+ | **package.json** | Contains npm dependencies as well as build scripts |
95
+ | **rollup.config.js** | config for babel and rollup combination |
96
+ | **setup.ts** | Test setup script |
97
+ | **tsconfig.json** | Config settings for TS transpiling |
98
+ | **tslint.json** | Config settings for TSLint code style checking |
99
+
100
+ ### :sparkles: Guidelines
101
+
102
+ ---
103
+
104
+ Remember that these packages will be consumed by other services, many of which are lambda's that have strict size restrictions.
105
+ Please be mindful of any packages you add here, as they could potentially cause inoperable deployments of ingesting services.
106
+ _Basically, only import if you really, really need it_
107
+
108
+ ## Import and usage syntax
109
+
110
+ ```
111
+ import {
112
+ isUnderSixteen,
113
+ FeatureFlag,
114
+ getAge,
115
+ getCurrencyFromCurrencyCode
116
+ makeMoneyString,
117
+ password
118
+ } from '@becollective/utils';
119
+
120
+ const isUnderSixteen = isUnderSixteen(birthdate);
121
+
122
+ const featureFlag = new FeatureFlag();
123
+ const isFeatureActive = await featureFlag.isFeatureActive(
124
+ 'this-is-a-feature-key',
125
+ { env: process.env.APP_ENV },
126
+ );
127
+
128
+ const ageInYears = getAge(birthdate);
129
+
130
+ const currency = getCurrencyFromCurrencyCode('AUD');
131
+
132
+ const dollarDollarBills = makeMoneyString({ amount: 100, currencyCode: 'AUD' });
133
+
134
+ const isValid = password.isValid('this-is-a-password');
135
+ ```
136
+
137
+ ---
138
+
139
+ ### Running npm scripts
140
+
141
+ | Npm Script | Description |
142
+ | ----------------- | ------------------------------------------ |
143
+ | `npm run test` | Run the tests |
144
+ | `npm run build` | runs rollup |
145
+ | `npm run prepare` | runs build (not sure why this is required) |
146
+
147
+ ### :red_circle: Common Issues & FAQ
148
+
149
+ ---
package/bundle.js CHANGED
@@ -35,7 +35,7 @@ var password = {
35
35
  validate: function validate(input) {
36
36
  if (typeof input !== 'string') {
37
37
  throw new Error('not-string');
38
- } else if (input.length < 8) {
38
+ } else if (input.length < 12) {
39
39
  throw new Error('invalid-length');
40
40
  }
41
41
 
@@ -66,7 +66,7 @@ var moment = require('moment-timezone');
66
66
  * @param {string} dateOfBirth
67
67
  * @param {string} unit the measurement of the the difference
68
68
  * The supported measurements are:
69
- * years, months, weeks, days, hours, minutes, and seconds.
69
+ * years, months, weeks, days, hours, minutes, and seconds.
70
70
  * @returns {number} age
71
71
  */
72
72
 
@@ -105,6 +105,14 @@ var isUnderSixteen = function isUnderSixteen(dateOfBirth) {
105
105
  var age = getAge(dateOfBirth);
106
106
  return isNaN(age) ? false : age < 16;
107
107
  };
108
+ var isUnderAge = function isUnderAge(dateOfBirth, limit) {
109
+ if (!dateOfBirth || !moment(dateOfBirth).isValid()) {
110
+ return false;
111
+ }
112
+
113
+ var age = getAge(dateOfBirth);
114
+ return isNaN(age) ? false : age < limit;
115
+ };
108
116
  var datesByThemselves = function datesByThemselves(a, b) {
109
117
  if (!a.from) return 1;
110
118
  return moment(a.from) - moment(b.from);
@@ -189,9 +197,9 @@ var readableOpportunityType = function readableOpportunityType(type) {
189
197
  var _require = require('lodash'),
190
198
  pick = _require.pick;
191
199
  /**
192
- *
193
- * @param {*} opportunityUser
194
- * @param {*} opportunity
200
+ *
201
+ * @param {*} opportunityUser
202
+ * @param {*} opportunity
195
203
  */
196
204
 
197
205
 
@@ -205,8 +213,8 @@ var getTimeInfo = function getTimeInfo(opportunityUser) {
205
213
  };
206
214
 
207
215
  /**
208
- *
209
- * @param {Array} locationList
216
+ *
217
+ * @param {Array} locationList
210
218
  */
211
219
  var getHomeLocalityFromLocationList = function getHomeLocalityFromLocationList(locationList) {
212
220
  var homeLocation = Array.isArray(locationList) && locationList.find(function (location) {
@@ -2843,54 +2851,38 @@ var followRedirects = wrap({ http: http__default['default'], https: https__defau
2843
2851
  var wrap_1 = wrap;
2844
2852
  followRedirects.wrap = wrap_1;
2845
2853
 
2846
- var _args = [
2847
- [
2848
- "axios@0.21.1",
2849
- "/codefresh/volume/becollective-npm/packages/utils"
2850
- ]
2851
- ];
2852
- var _from = "axios@0.21.1";
2853
- var _id = "axios@0.21.1";
2854
- var _inBundle = false;
2855
- var _integrity = "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==";
2856
- var _location = "/axios";
2857
- var _phantomChildren = {
2854
+ var name = "axios";
2855
+ var version = "0.21.1";
2856
+ var description = "Promise based HTTP client for the browser and node.js";
2857
+ var main = "index.js";
2858
+ var scripts = {
2859
+ test: "grunt test && bundlesize",
2860
+ start: "node ./sandbox/server.js",
2861
+ build: "NODE_ENV=production grunt build",
2862
+ preversion: "npm test",
2863
+ version: "npm run build && grunt version && git add -A dist && git add CHANGELOG.md bower.json package.json",
2864
+ postversion: "git push && git push --tags",
2865
+ examples: "node ./examples/server.js",
2866
+ coveralls: "cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
2867
+ fix: "eslint --fix lib/**/*.js"
2858
2868
  };
2859
- var _requested = {
2860
- type: "version",
2861
- registry: true,
2862
- raw: "axios@0.21.1",
2863
- name: "axios",
2864
- escapedName: "axios",
2865
- rawSpec: "0.21.1",
2866
- saveSpec: null,
2867
- fetchSpec: "0.21.1"
2869
+ var repository = {
2870
+ type: "git",
2871
+ url: "https://github.com/axios/axios.git"
2868
2872
  };
2869
- var _requiredBy = [
2870
- "/"
2873
+ var keywords = [
2874
+ "xhr",
2875
+ "http",
2876
+ "ajax",
2877
+ "promise",
2878
+ "node"
2871
2879
  ];
2872
- var _resolved = "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz";
2873
- var _spec = "0.21.1";
2874
- var _where = "/codefresh/volume/becollective-npm/packages/utils";
2875
- var author = {
2876
- name: "Matt Zabriskie"
2877
- };
2878
- var browser = {
2879
- "./lib/adapters/http.js": "./lib/adapters/xhr.js"
2880
- };
2880
+ var author = "Matt Zabriskie";
2881
+ var license = "MIT";
2881
2882
  var bugs = {
2882
2883
  url: "https://github.com/axios/axios/issues"
2883
2884
  };
2884
- var bundlesize = [
2885
- {
2886
- path: "./dist/axios.min.js",
2887
- threshold: "5kB"
2888
- }
2889
- ];
2890
- var dependencies = {
2891
- "follow-redirects": "^1.10.0"
2892
- };
2893
- var description = "Promise based HTTP client for the browser and node.js";
2885
+ var homepage = "https://github.com/axios/axios";
2894
2886
  var devDependencies = {
2895
2887
  bundlesize: "^0.17.0",
2896
2888
  coveralls: "^3.0.0",
@@ -2928,67 +2920,40 @@ var devDependencies = {
2928
2920
  webpack: "^1.13.1",
2929
2921
  "webpack-dev-server": "^1.14.1"
2930
2922
  };
2931
- var homepage = "https://github.com/axios/axios";
2932
- var jsdelivr = "dist/axios.min.js";
2933
- var keywords = [
2934
- "xhr",
2935
- "http",
2936
- "ajax",
2937
- "promise",
2938
- "node"
2939
- ];
2940
- var license = "MIT";
2941
- var main = "index.js";
2942
- var name = "axios";
2943
- var repository = {
2944
- type: "git",
2945
- url: "git+https://github.com/axios/axios.git"
2946
- };
2947
- var scripts = {
2948
- build: "NODE_ENV=production grunt build",
2949
- coveralls: "cat coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js",
2950
- examples: "node ./examples/server.js",
2951
- fix: "eslint --fix lib/**/*.js",
2952
- postversion: "git push && git push --tags",
2953
- preversion: "npm test",
2954
- start: "node ./sandbox/server.js",
2955
- test: "grunt test && bundlesize",
2956
- version: "npm run build && grunt version && git add -A dist && git add CHANGELOG.md bower.json package.json"
2923
+ var browser = {
2924
+ "./lib/adapters/http.js": "./lib/adapters/xhr.js"
2957
2925
  };
2958
- var typings = "./index.d.ts";
2926
+ var jsdelivr = "dist/axios.min.js";
2959
2927
  var unpkg = "dist/axios.min.js";
2960
- var version = "0.21.1";
2928
+ var typings = "./index.d.ts";
2929
+ var dependencies = {
2930
+ "follow-redirects": "^1.10.0"
2931
+ };
2932
+ var bundlesize = [
2933
+ {
2934
+ path: "./dist/axios.min.js",
2935
+ threshold: "5kB"
2936
+ }
2937
+ ];
2961
2938
  var pkg = {
2962
- _args: _args,
2963
- _from: _from,
2964
- _id: _id,
2965
- _inBundle: _inBundle,
2966
- _integrity: _integrity,
2967
- _location: _location,
2968
- _phantomChildren: _phantomChildren,
2969
- _requested: _requested,
2970
- _requiredBy: _requiredBy,
2971
- _resolved: _resolved,
2972
- _spec: _spec,
2973
- _where: _where,
2939
+ name: name,
2940
+ version: version,
2941
+ description: description,
2942
+ main: main,
2943
+ scripts: scripts,
2944
+ repository: repository,
2945
+ keywords: keywords,
2974
2946
  author: author,
2975
- browser: browser,
2947
+ license: license,
2976
2948
  bugs: bugs,
2977
- bundlesize: bundlesize,
2978
- dependencies: dependencies,
2979
- description: description,
2980
- devDependencies: devDependencies,
2981
2949
  homepage: homepage,
2950
+ devDependencies: devDependencies,
2951
+ browser: browser,
2982
2952
  jsdelivr: jsdelivr,
2983
- keywords: keywords,
2984
- license: license,
2985
- main: main,
2986
- name: name,
2987
- repository: repository,
2988
- scripts: scripts,
2989
- typings: typings,
2990
2953
  unpkg: unpkg,
2991
- version: version
2954
+ typings: typings,
2955
+ dependencies: dependencies,
2956
+ bundlesize: bundlesize
2992
2957
  };
2993
2958
 
2994
2959
  var httpFollow = followRedirects.http;
@@ -21020,6 +20985,7 @@ class FeatureFlag {
21020
20985
  var util = {
21021
20986
  getAge: getAge,
21022
20987
  getCurrencyFromCurrencyCode: getCurrencyFromCurrencyCode,
20988
+ isUnderAge: isUnderAge,
21023
20989
  isUnderSixteen: isUnderSixteen,
21024
20990
  makeMoneyString: makeMoneyString,
21025
20991
  password: password,
package/index.js CHANGED
@@ -1,10 +1,5 @@
1
1
  import { password } from './src/password';
2
- import {
3
- isUnderSixteen,
4
- getAge,
5
- datesByThemselves,
6
- getShiftText,
7
- } from './src/date-time';
2
+ import { isUnderSixteen, isUnderAge, getAge, datesByThemselves, getShiftText } from './src/date-time';
8
3
  import { getCurrencyFromCurrencyCode, makeMoneyString } from './src/money';
9
4
  import { readableOpportunityType } from './src/opportunity';
10
5
  import { getTimeInfo } from './src/opportunityUser';
@@ -13,6 +8,7 @@ import FeatureFlag from './src/FeatureFlag';
13
8
  const util = {
14
9
  getAge,
15
10
  getCurrencyFromCurrencyCode,
11
+ isUnderAge,
16
12
  isUnderSixteen,
17
13
  makeMoneyString,
18
14
  password,
package/jestconfig.json CHANGED
@@ -5,7 +5,5 @@
5
5
  "testRegex": "(/tests/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
6
6
  "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"],
7
7
  "collectCoverage": true,
8
- "setupFiles": [
9
- "./setup.ts"
10
- ]
8
+ "setupFiles": ["./setup.ts"]
11
9
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@becollective/utils",
3
- "version": "1.7.1",
3
+ "version": "1.9.0",
4
4
  "description": "Common utilities",
5
5
  "main": "bundle.js",
6
6
  "scripts": {
package/rollup.config.js CHANGED
@@ -8,7 +8,7 @@ export default {
8
8
  input: 'index.js',
9
9
  output: {
10
10
  file: 'bundle.js',
11
- format: 'cjs'
11
+ format: 'cjs',
12
12
  },
13
13
  plugins: [
14
14
  json(),
@@ -18,9 +18,7 @@ export default {
18
18
  babel({
19
19
  exclude: 'node_modules/**', // only transpile our source code
20
20
  babelrc: false,
21
- presets: [
22
- "@babel/preset-env",
23
- ],
21
+ presets: ['@babel/preset-env'],
24
22
  }),
25
23
  ],
26
24
  };
package/setup.ts CHANGED
@@ -1,7 +1,4 @@
1
1
  // Jest will set NODE_ENV to "test" if not specified
2
- if (
3
- process.env.NODE_ENV !== 'compose' &&
4
- process.env.NODE_ENV !== 'localtest'
5
- ) {
2
+ if (process.env.NODE_ENV !== 'compose' && process.env.NODE_ENV !== 'localtest') {
6
3
  process.env.NODE_ENV = 'localtest';
7
4
  }
@@ -1,10 +1,7 @@
1
1
  import axios from 'axios';
2
2
  import { memoize, get as lodashGet } from 'lodash';
3
3
 
4
- const fetchFeatureActive = async (
5
- feature: string,
6
- options: { env: string; region?: string },
7
- ): Promise<boolean> => {
4
+ const fetchFeatureActive = async (feature: string, options: { env: string; region?: string }): Promise<boolean> => {
8
5
  const getFlagByFeatureUrl = `https://lb-central.becollective.com/api/v2/feature-flags/${feature}`;
9
6
  let isFeatureActive = false;
10
7
  const featureFlags = await axios.get(getFlagByFeatureUrl);
@@ -15,9 +12,7 @@ const fetchFeatureActive = async (
15
12
  return isFeatureActive;
16
13
  };
17
14
 
18
- const memoizedFeatureActive = memoize(fetchFeatureActive, (feature, options) =>
19
- JSON.stringify({ feature, options }),
20
- );
15
+ const memoizedFeatureActive = memoize(fetchFeatureActive, (feature, options) => JSON.stringify({ feature, options }));
21
16
 
22
17
  class FeatureFlag {
23
18
  ttl: number;
@@ -26,10 +21,7 @@ class FeatureFlag {
26
21
  this.ttl = ttl || 1000 * 60 * 5; // default to 5 minutes
27
22
  this.expiry = Date.now() + ttl;
28
23
  }
29
- async isFeatureActive(
30
- feature: string,
31
- options: { env: string; region?: string },
32
- ): Promise<boolean> {
24
+ async isFeatureActive(feature: string, options: { env: string; region?: string }): Promise<boolean> {
33
25
  // Lazy expiration upon function call
34
26
  const now = Date.now();
35
27
  if (now >= this.expiry) {
package/src/date-time.js CHANGED
@@ -5,10 +5,10 @@ const moment = require('moment-timezone');
5
5
  * @param {string} dateOfBirth
6
6
  * @param {string} unit the measurement of the the difference
7
7
  * The supported measurements are:
8
- * years, months, weeks, days, hours, minutes, and seconds.
8
+ * years, months, weeks, days, hours, minutes, and seconds.
9
9
  * @returns {number} age
10
10
  */
11
- export const getAge = (dateOfBirth, unit='years') => {
11
+ export const getAge = (dateOfBirth, unit = 'years') => {
12
12
  const age = moment().diff(dateOfBirth, unit);
13
13
  if (isNaN(age)) {
14
14
  throw new Error('Invalid date');
@@ -30,7 +30,7 @@ export const getAge = (dateOfBirth, unit='years') => {
30
30
  * data to have a consistent birthdate property.
31
31
  * Then we should throw error if birthdate is not valid
32
32
  */
33
- export const isUnderSixteen = dateOfBirth => {
33
+ export const isUnderSixteen = (dateOfBirth) => {
34
34
  if (!dateOfBirth || !moment(dateOfBirth).isValid()) {
35
35
  return false;
36
36
  }
@@ -38,6 +38,14 @@ export const isUnderSixteen = dateOfBirth => {
38
38
  return isNaN(age) ? false : age < 16;
39
39
  };
40
40
 
41
+ export const isUnderAge = (dateOfBirth, limit) => {
42
+ if (!dateOfBirth || !moment(dateOfBirth).isValid()) {
43
+ return false;
44
+ }
45
+ const age = getAge(dateOfBirth);
46
+ return isNaN(age) ? false : age < limit;
47
+ };
48
+
41
49
  export const datesByThemselves = (a, b) => {
42
50
  if (!a.from) return 1;
43
51
  return moment(a.from) - moment(b.from);
@@ -49,7 +57,8 @@ export const getShiftText = (from, to, timezone) => {
49
57
  const startToTimezone = moment(from).tz(timezone);
50
58
  const endToTimezone = moment(to).tz(timezone);
51
59
  return `${moment(startToTimezone).format('dddd, DD MMMM YYYY, h:mma')}-${moment(endToTimezone).format('h:mma')}`;
52
- } catch (e) {
60
+ }
61
+ catch (e) {
53
62
  return '';
54
63
  }
55
64
  };
package/src/locality.js CHANGED
@@ -1,10 +1,9 @@
1
1
  /**
2
- *
3
- * @param {Array} locationList
2
+ *
3
+ * @param {Array} locationList
4
4
  */
5
5
  export const getHomeLocalityFromLocationList = (locationList) => {
6
- const homeLocation = Array.isArray(locationList) &&
7
- locationList.find((location) => location.name === 'Home');
6
+ const homeLocation = Array.isArray(locationList) && locationList.find((location) => location.name === 'Home');
8
7
 
9
8
  if (homeLocation && homeLocation.locality && homeLocation.locality.long) {
10
9
  return homeLocation.locality.long;
package/src/money.js CHANGED
@@ -3,7 +3,7 @@ const { currencies } = require('@becollective/constants');
3
3
  // We should probably throw and error on bad input instead of falling back to a default.
4
4
  // We're making an assumption that whoever is calling this function can safely work
5
5
  // with AUD. But this assumption removes a lot of error handling elsewhere.
6
- export const getCurrencyFromCurrencyCode = currencyCode => {
6
+ export const getCurrencyFromCurrencyCode = (currencyCode) => {
7
7
  if (typeof currencyCode !== 'string' || !currencies[currencyCode]) {
8
8
  console.error(new Error(`Invalid currencyCode: ${currencyCode}. Falling back to 'AUD'.`));
9
9
  return currencies.AUD;
@@ -12,12 +12,7 @@ export const getCurrencyFromCurrencyCode = currencyCode => {
12
12
  return currencies[currencyCode];
13
13
  };
14
14
 
15
- export const makeMoneyString = ({
16
- amount: inputAmount,
17
- currencyCode,
18
- rounded = false,
19
- showCurrencyCode = false,
20
- }) => {
15
+ export const makeMoneyString = ({ amount: inputAmount, currencyCode, rounded = false, showCurrencyCode = false }) => {
21
16
  let amount = Number(inputAmount);
22
17
  if (isNaN(amount)) {
23
18
  console.error(new Error(`Invalid amount: ${inputAmount}. Falling back to 0.`));
@@ -6,4 +6,4 @@ const TYPE_MAP = {
6
6
  [opportunityTypes.flexible]: 'Flexible',
7
7
  };
8
8
 
9
- export const readableOpportunityType = type => TYPE_MAP[type] || null;
9
+ export const readableOpportunityType = (type) => TYPE_MAP[type] || null;
@@ -1,16 +1,25 @@
1
1
  const { pick } = require('lodash');
2
2
 
3
3
  /**
4
- *
5
- * @param {*} opportunityUser
6
- * @param {*} opportunity
4
+ *
5
+ * @param {*} opportunityUser
6
+ * @param {*} opportunity
7
7
  */
8
8
  export const getTimeInfo = (opportunityUser, opportunity = null) => {
9
9
  const opp = opportunity || opportunityUser.opportunity;
10
10
  const isEoi = (opportunityUser && opportunityUser.eoi) || (opp && opp.eoi);
11
11
  const record = isEoi ? opportunityUser : opp;
12
- const fields = pick(record, ['startDate', 'endDate', 'type', 'dates',
13
- 'recurrenceRule', 'timezone', 'location', 'locationOther', 'locationVirtual']);
12
+ const fields = pick(record, [
13
+ 'startDate',
14
+ 'endDate',
15
+ 'type',
16
+ 'dates',
17
+ 'recurrenceRule',
18
+ 'timezone',
19
+ 'location',
20
+ 'locationOther',
21
+ 'locationVirtual',
22
+ ]);
14
23
 
15
24
  return fields;
16
25
  };
package/src/password.js CHANGED
@@ -9,17 +9,18 @@ export const password = {
9
9
  return !!input.match(/[0-9]/);
10
10
  },
11
11
  validate: (input) => {
12
- if(typeof input !== 'string') {
12
+ if (typeof input !== 'string') {
13
13
  throw new Error('not-string');
14
- } else if(input.length < 8) {
14
+ }
15
+ else if (input.length < 12) {
15
16
  throw new Error('invalid-length');
16
17
  }
17
18
 
18
19
  let rules = 0;
19
- if(password.hasUppercase(input)) rules++;
20
- if(password.hasLowerCase(input)) rules++;
21
- if(password.hasNumeral(input)) rules++;
22
- if(rules < 3) {
20
+ if (password.hasUppercase(input)) rules++;
21
+ if (password.hasLowerCase(input)) rules++;
22
+ if (password.hasNumeral(input)) rules++;
23
+ if (rules < 3) {
23
24
  throw new Error('invalid-minimum-rules');
24
25
  }
25
26
 
@@ -31,7 +32,7 @@ export const password = {
31
32
  return true;
32
33
  }
33
34
  catch (e) {
34
- return false
35
+ return false;
35
36
  }
36
- }
37
- }
37
+ },
38
+ };
@@ -1,4 +1,4 @@
1
- const { isUnderSixteen, getAge, getShiftText } = require('../bundle.js');
1
+ const { isUnderSixteen, isUnderAge, getAge, getShiftText } = require('../bundle.js');
2
2
  const moment = require('moment');
3
3
 
4
4
  describe('getAge', () => {
@@ -21,6 +21,7 @@ describe('getAge', () => {
21
21
  });
22
22
 
23
23
  test('Throws Error if dob is not a valid date-string', () => {
24
+ // eslint-disable-next-line no-undef
24
25
  expect(() => getAge(notDefined)).toThrow(/not defined/);
25
26
  expect(() => getAge(null)).toThrow(/Invalid date/);
26
27
  expect(() => getAge('not-valid')).toThrow(/Invalid date/);
@@ -55,16 +56,76 @@ describe('isUnderSixteen', () => {
55
56
  });
56
57
  });
57
58
 
59
+
60
+ describe('isUnderAge', () => {
61
+ const refPoint = moment().subtract(13, 'years');
62
+ const obj = {};
63
+ test('Is not U13 if dob is 13 years ago', () => {
64
+ const dob = moment(refPoint);
65
+
66
+ expect(isUnderAge(dob.subtract(1, 'minute').utc().format(), 13)).toBe(false);
67
+ expect(isUnderAge(dob.subtract(100, 'year').utc().format(), 13)).toBe(false);
68
+ });
69
+
70
+ test('Is U16 if dob is less than 16 years ago', () => {
71
+ const dob = moment(refPoint);
72
+
73
+ expect(isUnderAge(dob.add(1, 'minute').utc().format(), 13)).toBe(true);
74
+ expect(isUnderAge(dob.add(100, 'year').utc().format(), 13)).toBe(true);
75
+ });
76
+
77
+ test('Undefined dob', () => {
78
+ expect(isUnderAge(obj.notDefined, 13)).toBe(false);
79
+ });
80
+ test('Null dob', () => {
81
+ expect(isUnderAge(null, 13)).toBe(false);
82
+ });
83
+ test('Invalid date string', () => {
84
+ expect(isUnderAge('not-valid', 13)).toBe(false);
85
+ });
86
+ });
87
+
88
+
89
+ describe('isUnderAge - 10', () => {
90
+ const refPoint = moment().subtract(10, 'years');
91
+ const obj = {};
92
+ test('Is not U13 if dob is 10 years ago', () => {
93
+ const dob = moment(refPoint);
94
+
95
+ expect(isUnderAge(dob.subtract(1, 'minute').utc().format(), 10)).toBe(false);
96
+ expect(isUnderAge(dob.subtract(100, 'year').utc().format(), 10)).toBe(false);
97
+ });
98
+
99
+ test('Is U10 if dob is less than 10 years ago', () => {
100
+ const dob = moment(refPoint);
101
+
102
+ expect(isUnderAge(dob.add(1, 'minute').utc().format(), 10)).toBe(true);
103
+ expect(isUnderAge(dob.add(100, 'year').utc().format(), 10)).toBe(true);
104
+ });
105
+ });
106
+
107
+
108
+ describe('isUnderAge - over 13', () => {
109
+ const refPoint = moment().subtract(15, 'years');
110
+ const obj = {};
111
+ test('Is not U13 if dob is 15 years ago', () => {
112
+ const dob = moment(refPoint);
113
+
114
+ expect(isUnderAge(dob.subtract(1, 'minute').utc().format(), 15)).toBe(false);
115
+ expect(isUnderAge(dob.subtract(100, 'year').utc().format(), 15)).toBe(false);
116
+ });
117
+ });
118
+
58
119
  describe('getShiftText', () => {
59
120
  const from = new Date(Date.UTC(2020, 6, 30, 0, 0, 0));
60
121
  const to = new Date(Date.UTC(2020, 6, 30, 5, 30, 0));
61
122
  const melbourne = 'Australia/Melbourne';
62
123
  const auckland = 'Pacific/Auckland';
63
124
  test('get shift text with melbourne timezone', () => {
64
- expect(getShiftText(from, to,melbourne)).toBe("Thursday, 30 July 2020, 10:00am-3:30pm");
125
+ expect(getShiftText(from, to, melbourne)).toBe('Thursday, 30 July 2020, 10:00am-3:30pm');
65
126
  });
66
127
  test('get shift text with auckland timezone', () => {
67
- expect(getShiftText(from, to,auckland)).toBe("Thursday, 30 July 2020, 12:00pm-5:30pm");
128
+ expect(getShiftText(from, to, auckland)).toBe('Thursday, 30 July 2020, 12:00pm-5:30pm');
68
129
  });
69
130
  test('with empty data', () => {
70
131
  expect(getShiftText()).toBe('');
@@ -11,7 +11,7 @@ describe('Make feature decision based on feature flags', () => {
11
11
  mockAxios.get.mockReturnValue(
12
12
  Promise.resolve({
13
13
  data: { Environments: ['localtest', 'compose'] },
14
- }),
14
+ })
15
15
  );
16
16
  const isActive = await featureFlag.isFeatureActive(feature, {
17
17
  env: 'localtest',
@@ -23,7 +23,7 @@ describe('Make feature decision based on feature flags', () => {
23
23
  mockAxios.get.mockReturnValue(
24
24
  Promise.resolve({
25
25
  data: { Environments: ['dev-au'] },
26
- }),
26
+ })
27
27
  );
28
28
  const isActive = await featureFlag.isFeatureActive(feature, {
29
29
  env: 'localtest',
@@ -44,7 +44,7 @@ describe('Make feature decision based on feature flags', () => {
44
44
  mockAxios.get.mockReturnValue(
45
45
  Promise.resolve({
46
46
  data: { Environments: ['localtest', 'compose'] },
47
- }),
47
+ })
48
48
  );
49
49
  const isActive = await featureFlag.isFeatureActive(feature, {
50
50
  env: 'localtest',
@@ -64,7 +64,7 @@ describe('Make feature decision based on feature flags', () => {
64
64
  mockAxios.get.mockReturnValue(
65
65
  Promise.resolve({
66
66
  data: { Environments: ['localtest', 'compose'] },
67
- }),
67
+ })
68
68
  );
69
69
  const isActive = await featureFlag.isFeatureActive(feature, {
70
70
  env: 'localtest',
@@ -84,7 +84,7 @@ describe('Make feature decision based on feature flags', () => {
84
84
  mockAxios.get.mockReturnValue(
85
85
  Promise.resolve({
86
86
  data: { Environments: ['localtest', 'compose'] },
87
- }),
87
+ })
88
88
  );
89
89
  const isActive = await featureFlag.isFeatureActive(feature, {
90
90
  env: 'localtest',
@@ -10,13 +10,8 @@ describe('getCurrencyFromCurrencyCode', () => {
10
10
  });
11
11
 
12
12
  test('Returns AUD currency if currencyCode not found or invalid', () => {
13
- const bogusCurrencyCodes = [
14
- undefined,
15
- 1234,
16
- 'some junk that is not a currency code',
17
- { foo: 'bar' },
18
- ];
19
- bogusCurrencyCodes.forEach(bogusCurrencyCode => {
13
+ const bogusCurrencyCodes = [undefined, 1234, 'some junk that is not a currency code', { foo: 'bar' }];
14
+ bogusCurrencyCodes.forEach((bogusCurrencyCode) => {
20
15
  expect(getCurrencyFromCurrencyCode(bogusCurrencyCode)).toMatchObject(currencies.AUD);
21
16
  });
22
17
  });
@@ -60,13 +55,8 @@ describe('makeMoneyString', () => {
60
55
  });
61
56
 
62
57
  test('Outputs a money string for AUD if bad input is provided', () => {
63
- const bogusCurrencyCodes = [
64
- undefined,
65
- 1234,
66
- 'some junk that is not a currency code',
67
- { foo: 'bar' },
68
- ];
69
- bogusCurrencyCodes.forEach(bogusCurrencyCode => {
58
+ const bogusCurrencyCodes = [undefined, 1234, 'some junk that is not a currency code', { foo: 'bar' }];
59
+ bogusCurrencyCodes.forEach((bogusCurrencyCode) => {
70
60
  expect(
71
61
  makeMoneyString({
72
62
  amount: 123.05,
@@ -87,7 +77,7 @@ describe('makeMoneyString', () => {
87
77
  ).toEqual('£100');
88
78
 
89
79
  const bogusAmountValues = [undefined, null, 'some junk that is not a number', { foo: 'bar' }];
90
- bogusAmountValues.forEach(bogusAmountValue => {
80
+ bogusAmountValues.forEach((bogusAmountValue) => {
91
81
  expect(
92
82
  makeMoneyString({
93
83
  amount: bogusAmountValue,
@@ -2,11 +2,12 @@ const util = require('../bundle.js');
2
2
 
3
3
  describe('password.valiate', () => {
4
4
  test('validate a valid password', async () => {
5
- const password = 'Password123';
5
+ const password = 'Password123456';
6
6
  let result;
7
7
  try {
8
8
  result = util.password.validate(password);
9
- } catch(e) {
9
+ }
10
+ catch (e) {
10
11
  result = e;
11
12
  }
12
13
  expect(result).toBe(true);
@@ -18,13 +19,13 @@ describe('password.valiate', () => {
18
19
  }).toThrow('invalid-length');
19
20
  }, 1000);
20
21
  test('validate a one rule password', async () => {
21
- const password = 'foobarab';
22
+ const password = 'foobarabpcip';
22
23
  expect(() => {
23
24
  util.password.validate(password);
24
25
  }).toThrow('invalid-minimum-rules');
25
26
  }, 1000);
26
27
  test('validate a two rule password', async () => {
27
- const password = 'foobar123';
28
+ const password = 'foobarpcip123';
28
29
  expect(() => {
29
30
  util.password.validate(password);
30
31
  }).toThrow('invalid-minimum-rules');
@@ -47,14 +48,7 @@ describe('password.valiate', () => {
47
48
  }).toThrow('not-string');
48
49
  }, 1000);
49
50
  test('returns false for invalid passwords', async () => {
50
- const someValid = [
51
- 'short',
52
- '1234567a',
53
- '123456aa',
54
- '1aB!',
55
- ]
56
- .map(util.password.isValid)
57
- .some(val => val);
51
+ const someValid = ['short', '1234567a', '123456aa', '1aB!'].map(util.password.isValid).some((val) => val);
58
52
  expect(someValid).toBe(false);
59
53
  });
60
54
  test('returns true for a valid password', async () => {
package/tslint.json CHANGED
@@ -1,51 +1,30 @@
1
1
  {
2
2
  "extends": ["tslint:recommended", "tslint-config-prettier"],
3
3
  "rules": {
4
- "align": [
5
- true,
6
- "parameters",
7
- "arguments",
8
- "statements"
9
- ],
4
+ "align": [true, "parameters", "arguments", "statements"],
10
5
  "ban": false,
11
6
  "class-name": true,
12
- "comment-format": [
13
- true,
14
- "check-space"
15
- ],
7
+ "comment-format": [true, "check-space"],
16
8
  "curly": true,
17
9
  "eofline": false,
18
10
  "forin": true,
19
- "indent": [ true, "spaces" ],
11
+ "indent": [true, "spaces"],
20
12
  "interface-name": [true, "never-prefix"],
21
13
  "jsdoc-format": true,
22
14
  "jsx-no-lambda": false,
23
15
  "jsx-no-multiline-js": false,
24
16
  "label-position": true,
25
- "max-line-length": [ true, 120 ],
17
+ "max-line-length": [true, 120],
26
18
  "member-ordering": [
27
19
  true,
28
20
  {
29
- "order": [
30
- "public-before-private",
31
- "static-before-instance",
32
- "variables-before-functions"
33
- ]
21
+ "order": ["public-before-private", "static-before-instance", "variables-before-functions"]
34
22
  }
35
23
  ],
36
24
  "no-any": true,
37
25
  "no-arg": true,
38
26
  "no-bitwise": true,
39
- "no-console": [
40
- true,
41
- "log",
42
- "error",
43
- "debug",
44
- "info",
45
- "time",
46
- "timeEnd",
47
- "trace"
48
- ],
27
+ "no-console": [true, "log", "error", "debug", "info", "time", "timeEnd", "trace"],
49
28
  "no-consecutive-blank-lines": true,
50
29
  "no-construct": true,
51
30
  "no-debugger": true,
@@ -57,24 +36,16 @@
57
36
  "no-switch-case-fall-through": true,
58
37
  "no-trailing-whitespace": false,
59
38
  "no-unused-expression": true,
60
- "one-line": [
61
- true,
62
- "check-open-brace",
63
- "check-whitespace"
64
- ],
39
+ "one-line": [true, "check-open-brace", "check-whitespace"],
65
40
  "quotemark": [true, "single", "jsx-double"],
66
41
  "radix": true,
67
42
  "semicolon": [true, "always"],
68
43
  "switch-default": true,
69
44
 
70
- "trailing-comma": [true, {"multiline": "always", "singleline": "never"}],
45
+ "trailing-comma": [true, { "multiline": "always", "singleline": "never" }],
71
46
 
72
- "triple-equals": [ true, "allow-null-check" ],
73
- "typedef": [
74
- true,
75
- "parameter",
76
- "property-declaration"
77
- ],
47
+ "triple-equals": [true, "allow-null-check"],
48
+ "typedef": [true, "parameter", "property-declaration"],
78
49
  "typedef-whitespace": [
79
50
  true,
80
51
  {