@barchart/portfolio-api-common 1.3.21 → 1.3.25

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.
package/.jshintrc CHANGED
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "esversion": 6,
3
3
  "validthis": true,
4
- "-W018": true
4
+ "-W018": true,
5
+ "-W093": true
5
6
  }
package/README.md CHANGED
@@ -1,7 +1,32 @@
1
1
  # @barchart/portfolio-api-common
2
- ## Barchart Portfolio API Common Components
3
2
 
4
- Shared code, used by the serverless application and the client-side SDK. See:
3
+ [![AWS CodeBuild](https://codebuild.us-east-1.amazonaws.com/badges?uuid=eyJlbmNyeXB0ZWREYXRhIjoiSXBJTDZKWVFmSGVOSG9XQUgwbzB3Um5BZ0JsN2h1U3NQNWNhZTRHMlJKTVpEVVlVMENPaEFmR0NYS29rSStZWmZ5M1d0YVh2eXErVGhiekFtdHBpVmhJPSIsIml2UGFyYW1ldGVyU3BlYyI6ImROM3ZLMURwaXFyekltdDYiLCJtYXRlcmlhbFNldFNlcmlhbCI6MX0%3D&branch=master)](https://github.com/barchart/portfolio-api-common)
5
4
 
6
- * https://github.com/barchart/aws-lambda-portfolio and
7
- * https://github.com/barchart/portfolio-client-js
5
+ A *private* library of shared JavaScript code pertaining to the paper-trading portfolio system.
6
+
7
+ ### Overview
8
+
9
+ Simply put, this project contains code that runs on both the servers (i.e. Serverless applications) and clients (e.g. browser, mobile, etc).
10
+
11
+ #### [lib/serialization](https://github.com/barchart/portfolio-api-common/tree/master/lib/serialization)
12
+
13
+ Data is passed between client and server in JSON format. However, the code works with more complex types. For example, [Decimal](https://github.com/barchart/barchart-common-js/blob/master/lang/Decimal.js) instances are used in place of [native JavaScript floats](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number). [Day](https://github.com/barchart/barchart-common-js/blob/master/lang/Day.js) instances are used instead of [native JavaScript Dates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date).
14
+
15
+ So, before data is exchanged, it must be converted to pure JSON. Conversely, when data is received, as pure JSON, its translated into more complex types before use. This is facilitated by the [Schema](https://github.com/barchart/barchart-common-js/blob/master/serialization/json/Schema.js) definitions which build custom "reviver" functions for [JSON parsing](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse).
16
+
17
+ #### [lib/processing](https://github.com/barchart/portfolio-api-common/tree/master/lib/processing)
18
+
19
+ For reporting and display purposes, positions can be grouped together (by asset class, by portfolio, by user, etc). This code supports aggregation and gain/loss calculation. It is used by server-generated reports and dynamic user interfaces.
20
+
21
+ ### Notable Consumers
22
+
23
+ * [aws-lambda-portfolio](https://github.com/barchart/aws-lambda-portfolio) - Serverless applications (i.e. the servers)
24
+ * [portfolio-client-js](https://github.com/barchart/portfolio-client-js) - JavaScript client SDK for communicating with server API's.
25
+ * [tgam-portfolio-ui-js](https://github.com/barchart/tgam-portfolio-ui-js) - A dynamic, single-page HTML UI.
26
+
27
+ ### Package Managers
28
+
29
+ This library has been published as a *private* module to NPM as [@barchart/portfolio-api-common](https://www.npmjs.com/package/@barchart/portfolio-api-common).
30
+
31
+ > npm login
32
+ > npm install @barchart/portfolio-api-common -S
package/buildspec.yml ADDED
@@ -0,0 +1,15 @@
1
+ version: 0.2
2
+
3
+ phases:
4
+ install:
5
+ runtime-versions:
6
+ nodejs: 12.x
7
+
8
+ pre_build:
9
+ commands:
10
+ - npm install
11
+
12
+ build:
13
+ commands:
14
+ - ./node_modules/.bin/gulp lint
15
+ - ./node_modules/.bin/gulp test
package/gulpfile.js CHANGED
@@ -5,7 +5,6 @@ const fs = require('fs');
5
5
  const browserify = require('browserify'),
6
6
  buffer = require('vinyl-buffer'),
7
7
  bump = require('gulp-bump'),
8
- exec = require('child_process').exec,
9
8
  git = require('gulp-git'),
10
9
  gitStatus = require('git-get-status'),
11
10
  glob = require('glob'),
@@ -14,7 +13,7 @@ const browserify = require('browserify'),
14
13
  source = require('vinyl-source-stream');
15
14
 
16
15
  function getVersionFromPackage() {
17
- return JSON.parse(fs.readFileSync('./package.json', 'utf8')).version;
16
+ return JSON.parse(fs.readFileSync('./package.json', 'utf8')).version;
18
17
  }
19
18
 
20
19
  gulp.task('ensure-clean-working-directory', (cb) => {
@@ -33,35 +32,26 @@ gulp.task('bump-version', () => {
33
32
  .pipe(gulp.dest('./'));
34
33
  });
35
34
 
36
- gulp.task('document', (cb) => {
37
- exec('jsdoc . -c jsdoc.json -r -d docs', (error, stdout, stderr) => {
38
- console.log(stdout);
39
- console.log(stderr);
40
-
41
- cb();
42
- });
43
- });
44
-
45
35
  gulp.task('commit-changes', () => {
46
- return gulp.src([ './', './test/', './package.json' ])
47
- .pipe(git.add())
48
- .pipe(git.commit('Release. Bump version number'));
36
+ return gulp.src([ './', './test/', './package.json' ])
37
+ .pipe(git.add())
38
+ .pipe(git.commit('Release. Bump version number'));
49
39
  });
50
40
 
51
41
  gulp.task('push-changes', (cb) => {
52
- git.push('origin', 'master', cb);
42
+ git.push('origin', 'master', cb);
53
43
  });
54
44
 
55
45
  gulp.task('create-tag', (cb) => {
56
- const version = getVersionFromPackage();
46
+ const version = getVersionFromPackage();
57
47
 
58
- git.tag(version, 'Release ' + version, (error) => {
59
- if (error) {
60
- return cb(error);
61
- }
48
+ git.tag(version, 'Release ' + version, (error) => {
49
+ if (error) {
50
+ return cb(error);
51
+ }
62
52
 
63
- git.push('origin', 'master', { args: '--tags' }, cb);
64
- });
53
+ git.push('origin', 'master', { args: '--tags' }, cb);
54
+ });
65
55
  });
66
56
 
67
57
  gulp.task('build-test-bundle', () => {
@@ -73,13 +63,13 @@ gulp.task('build-test-bundle', () => {
73
63
  });
74
64
 
75
65
  gulp.task('execute-browser-tests', () => {
76
- return gulp.src('test/SpecRunner.js')
77
- .pipe(jasmine());
66
+ return gulp.src('test/SpecRunner.js')
67
+ .pipe(jasmine());
78
68
  });
79
69
 
80
70
  gulp.task('execute-node-tests', () => {
81
- return gulp.src(['test/specs/**/*.js'])
82
- .pipe(jasmine());
71
+ return gulp.src(['test/specs/**/*.js'])
72
+ .pipe(jasmine());
83
73
  });
84
74
 
85
75
  gulp.task('execute-tests', gulp.series(
@@ -91,7 +81,6 @@ gulp.task('execute-tests', gulp.series(
91
81
  gulp.task('release', gulp.series(
92
82
  'ensure-clean-working-directory',
93
83
  'execute-tests',
94
- 'document',
95
84
  'bump-version',
96
85
  'commit-changes',
97
86
  'push-changes',
@@ -99,9 +88,10 @@ gulp.task('release', gulp.series(
99
88
  ));
100
89
 
101
90
  gulp.task('lint', () => {
102
- return gulp.src([ './**/*.js', './test/specs/**/*.js', '!./node_modules/**', '!./docs/**', '!./test/SpecRunner.js' ])
103
- .pipe(jshint({'esversion': 6}))
104
- .pipe(jshint.reporter('default'));
91
+ return gulp.src([ './**/*.js', './test/specs/**/*.js', '!./node_modules/**', '!./docs/**', '!./test/SpecRunner.js' ])
92
+ .pipe(jshint({'esversion': 6}))
93
+ .pipe(jshint.reporter('default'))
94
+ .pipe(jshint.reporter('fail'));
105
95
  });
106
96
 
107
97
  gulp.task('test', gulp.series('execute-tests'));
@@ -356,13 +356,13 @@ module.exports = (() => {
356
356
  const transactionCreateFailedInstrumentCorrupt = new FailureType('TRANSACTION_CREATE_FAILED_INSTRUMENT_CORRUPT', 'Unable to create transaction, corporate action history for {U|symbol} cannot be located.');
357
357
 
358
358
  const transactionDeleteFailedOutOfSequence = new FailureType('TRANSACTION_DELETE_FAILED_OUT_OF_SEQUENCE', 'Deleting any transaction, except for the most recent, will cause transaction history to be re-written. Please confirm your intent to re-write transaction history (which could take some time and alter the historical results for this position).');
359
- const transactionDeleteFailedNoTransaction = new FailureType('TRANSACTION_DELETE_FAILED_NO_TRANSACTION', 'Unable to delete transaction. The referenced transaction does not exist.');
359
+ const transactionDeleteFailedNoTransaction = new FailureType('TRANSACTION_DELETE_FAILED_NO_TRANSACTION', 'Unable to delete transaction. The referenced transaction does not exist.', false);
360
360
  const transactionDeleteFailedDirectionSwitchOnRewrite = new FailureType('TRANSACTION_DELETE_FAILED_DIRECTION_SWITCH_ON_REWRITE', 'Deleting this transaction would cause your history to be re-written and the position to switch from long to short (i.e. positive to negative) or vice versa.', false);
361
361
  const transactionDeleteFailedPositionLocked = new FailureType('TRANSACTION_DELETE_FAILED_POSITION_LOCKED', 'Unable to delete transaction, your {L|description} history is being recalculated. Please wait a minute or two and retry.');
362
362
  const transactionDeleteFailedTypeReserved = new FailureType('TRANSACTION_DELETE_FAILED_TYPE_RESERVED', 'Unable to delete {U|type.description} transaction, this type of transaction is managed by the system.');
363
363
 
364
364
  const transactionEditFailedInvalidDate = new FailureType('TRANSACTION_EDIT_FAILED_INVALID_DATE', 'Unable to edit transaction with given date.');
365
- const transactionEditFailedNoTransaction = new FailureType('TRANSACTION_EDIT_FAILED_NO_TRANSACTION', 'Unable to edit transaction. The referenced transaction does not exist.');
365
+ const transactionEditFailedNoTransaction = new FailureType('TRANSACTION_EDIT_FAILED_NO_TRANSACTION', 'Unable to edit transaction. The referenced transaction does not exist.', false);
366
366
  const transactionEditFailedTypeReserved = new FailureType('TRANSACTION_EDIT_FAILED_TYPE_RESERVED', 'Unable to edit {U|type.description} transaction, this type of transaction is managed by the system.');
367
367
 
368
368
  return PortfolioFailureType;
@@ -70,20 +70,20 @@ module.exports = (() => {
70
70
  return transactions.every((t) => {
71
71
  let valid = true;
72
72
 
73
- if (is.object(t.reference) && is.string(t.reference.root) && is.number(t.reference.sequence)) {
73
+ if (is.object(t.reference) && is.string(t.reference.root) && is.string(t.reference.transaction)) {
74
74
  const root = t.reference.root;
75
- const sequence = t.reference.sequence;
75
+ const transaction = t.reference.transaction;
76
76
 
77
77
  if (!references.hasOwnProperty(root)) {
78
78
  references[root] = [ ];
79
79
  }
80
80
 
81
- const sequences = references[root];
81
+ const transactions = references[root];
82
82
 
83
- if (sequences.some(s => s === sequence)) {
83
+ if (transactions.some(t => t === transaction)) {
84
84
  valid = false;
85
85
  } else {
86
- sequences.push(sequence);
86
+ transactions.push(transaction);
87
87
  }
88
88
  }
89
89
 
@@ -130,6 +130,7 @@ module.exports = (() => {
130
130
  const complete = new TransactionSchema(SchemaBuilder.withName('complete')
131
131
  .withField('portfolio', DataType.STRING)
132
132
  .withField('position', DataType.STRING)
133
+ .withField('transaction', DataType.STRING)
133
134
  .withField('sequence', DataType.NUMBER)
134
135
  .withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
135
136
  .withField('date', DataType.DAY)
@@ -138,7 +139,7 @@ module.exports = (() => {
138
139
  .withField('quantity', DataType.DECIMAL)
139
140
  .withField('fee', DataType.DECIMAL, true)
140
141
  .withField('reference.position', DataType.STRING, true)
141
- .withField('reference.sequence', DataType.NUMBER, true)
142
+ .withField('reference.transaction', DataType.STRING, true)
142
143
  .withField('snapshot.open', DataType.DECIMAL)
143
144
  .withField('snapshot.direction', DataType.forEnum(PositionDirection, 'PositionDirection'))
144
145
  .withField('snapshot.buys', DataType.DECIMAL)
@@ -179,6 +180,7 @@ module.exports = (() => {
179
180
  const client = new TransactionSchema(SchemaBuilder.withName('client')
180
181
  .withField('portfolio', DataType.STRING)
181
182
  .withField('position', DataType.STRING)
183
+ .withField('transaction', DataType.STRING)
182
184
  .withField('sequence', DataType.NUMBER)
183
185
  .withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
184
186
  .withField('date', DataType.DAY)
@@ -187,7 +189,7 @@ module.exports = (() => {
187
189
  .withField('quantity', DataType.DECIMAL)
188
190
  .withField('fee', DataType.DECIMAL, true)
189
191
  .withField('reference.position', DataType.STRING, true)
190
- .withField('reference.sequence', DataType.NUMBER, true)
192
+ .withField('reference.transaction', DataType.NUMBER, true)
191
193
  .withField('snapshot.open', DataType.DECIMAL)
192
194
  .withField('snapshot.direction', DataType.forEnum(PositionDirection, 'PositionDirection'))
193
195
  .withField('snapshot.buys', DataType.DECIMAL)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@barchart/portfolio-api-common",
3
- "version": "1.3.21",
4
- "description": "Common classes used by the Portfolio system",
3
+ "version": "1.3.25",
4
+ "description": "Common code used by the Portfolio system",
5
5
  "author": {
6
6
  "name": "Bryan Ingle",
7
7
  "email": "bryan.ingle@barchart.com",
@@ -22,7 +22,6 @@
22
22
  "gulp-bump": "~1.0.0",
23
23
  "gulp-git": "^2.9.0",
24
24
  "gulp-jasmine": "^2.2.1",
25
- "gulp-jsdoc3": "^1.0.1",
26
25
  "gulp-jshint": "~2.1.0",
27
26
  "jsdoc": "^3.5.5",
28
27
  "jshint": "2.9.5",
@@ -1357,20 +1357,20 @@ module.exports = (() => {
1357
1357
  return transactions.every((t) => {
1358
1358
  let valid = true;
1359
1359
 
1360
- if (is.object(t.reference) && is.string(t.reference.root) && is.number(t.reference.sequence)) {
1360
+ if (is.object(t.reference) && is.string(t.reference.root) && is.string(t.reference.transaction)) {
1361
1361
  const root = t.reference.root;
1362
- const sequence = t.reference.sequence;
1362
+ const transaction = t.reference.transaction;
1363
1363
 
1364
1364
  if (!references.hasOwnProperty(root)) {
1365
1365
  references[root] = [ ];
1366
1366
  }
1367
1367
 
1368
- const sequences = references[root];
1368
+ const transactions = references[root];
1369
1369
 
1370
- if (sequences.some(s => s === sequence)) {
1370
+ if (transactions.some(t => t === transaction)) {
1371
1371
  valid = false;
1372
1372
  } else {
1373
- sequences.push(sequence);
1373
+ transactions.push(transaction);
1374
1374
  }
1375
1375
  }
1376
1376
 
@@ -4980,6 +4980,7 @@ module.exports = (() => {
4980
4980
  const complete = new TransactionSchema(SchemaBuilder.withName('complete')
4981
4981
  .withField('portfolio', DataType.STRING)
4982
4982
  .withField('position', DataType.STRING)
4983
+ .withField('transaction', DataType.STRING)
4983
4984
  .withField('sequence', DataType.NUMBER)
4984
4985
  .withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
4985
4986
  .withField('date', DataType.DAY)
@@ -4988,7 +4989,7 @@ module.exports = (() => {
4988
4989
  .withField('quantity', DataType.DECIMAL)
4989
4990
  .withField('fee', DataType.DECIMAL, true)
4990
4991
  .withField('reference.position', DataType.STRING, true)
4991
- .withField('reference.sequence', DataType.NUMBER, true)
4992
+ .withField('reference.transaction', DataType.STRING, true)
4992
4993
  .withField('snapshot.open', DataType.DECIMAL)
4993
4994
  .withField('snapshot.direction', DataType.forEnum(PositionDirection, 'PositionDirection'))
4994
4995
  .withField('snapshot.buys', DataType.DECIMAL)
@@ -5029,6 +5030,7 @@ module.exports = (() => {
5029
5030
  const client = new TransactionSchema(SchemaBuilder.withName('client')
5030
5031
  .withField('portfolio', DataType.STRING)
5031
5032
  .withField('position', DataType.STRING)
5033
+ .withField('transaction', DataType.STRING)
5032
5034
  .withField('sequence', DataType.NUMBER)
5033
5035
  .withField('type', DataType.forEnum(TransactionType, 'TransactionType'))
5034
5036
  .withField('date', DataType.DAY)
@@ -5037,7 +5039,7 @@ module.exports = (() => {
5037
5039
  .withField('quantity', DataType.DECIMAL)
5038
5040
  .withField('fee', DataType.DECIMAL, true)
5039
5041
  .withField('reference.position', DataType.STRING, true)
5040
- .withField('reference.sequence', DataType.NUMBER, true)
5042
+ .withField('reference.transaction', DataType.NUMBER, true)
5041
5043
  .withField('snapshot.open', DataType.DECIMAL)
5042
5044
  .withField('snapshot.direction', DataType.forEnum(PositionDirection, 'PositionDirection'))
5043
5045
  .withField('snapshot.buys', DataType.DECIMAL)
@@ -7488,6 +7490,7 @@ module.exports = (() => {
7488
7490
  * item's value. If no matching item can be found, a null value is returned.
7489
7491
  *
7490
7492
  * @public
7493
+ * @static
7491
7494
  * @param {Function} type - The enumeration type.
7492
7495
  * @param {String} code - The enumeration item's code.
7493
7496
  * @returns {*|null}
@@ -7501,6 +7504,7 @@ module.exports = (() => {
7501
7504
  * Returns all of the enumeration's items (given an enumeration type).
7502
7505
  *
7503
7506
  * @public
7507
+ * @static
7504
7508
  * @param {Function} type - The enumeration to list.
7505
7509
  * @returns {Array}
7506
7510
  */
@@ -9029,11 +9033,11 @@ module.exports = (() => {
9029
9033
  simple(fn) {
9030
9034
  const cache = {};
9031
9035
  return x => {
9032
- if (cache.hasOwnProperty(x)) {
9033
- return cache[x];
9034
- } else {
9035
- return cache[x] = fn(x);
9036
+ if (!cache.hasOwnProperty(x)) {
9037
+ cache[x] = fn(x);
9036
9038
  }
9039
+
9040
+ return cache[x];
9037
9041
  };
9038
9042
  },
9039
9043
 
@@ -17842,8 +17846,8 @@ describe('When validating transaction order', () => {
17842
17846
  describe('When validating transaction references', () => {
17843
17847
  'use strict';
17844
17848
 
17845
- const build = (root, sequence) => {
17846
- return { reference: { root: root, sequence: sequence } };
17849
+ const build = (root, transaction) => {
17850
+ return { reference: { root: root, transaction: transaction } };
17847
17851
  };
17848
17852
 
17849
17853
  it('An array of zero transactions should be valid', () => {
@@ -17855,11 +17859,11 @@ describe('When validating transaction references', () => {
17855
17859
  });
17856
17860
 
17857
17861
  it('An array with distinct references should be valid', () => {
17858
- expect(TransactionValidator.validateReferences([ build('a', 1), build('a', 2), build('b', 1) ])).toEqual(true);
17862
+ expect(TransactionValidator.validateReferences([ build('a', 'x'), build('a', 'y'), build('b', 'y') ])).toEqual(true);
17859
17863
  });
17860
17864
 
17861
17865
  it('An array with non-distinct references should be not valid', () => {
17862
- expect(TransactionValidator.validateReferences([ build('a', 1), build('a', 2), build('b', 1), build('a', 2) ])).toEqual(false);
17866
+ expect(TransactionValidator.validateReferences([ build('a', 'x'), build('a', 'y'), build('b', 'x'), build('a', 'y') ])).toEqual(false);
17863
17867
  });
17864
17868
  });
17865
17869
 
@@ -58,8 +58,8 @@ describe('When validating transaction order', () => {
58
58
  describe('When validating transaction references', () => {
59
59
  'use strict';
60
60
 
61
- const build = (root, sequence) => {
62
- return { reference: { root: root, sequence: sequence } };
61
+ const build = (root, transaction) => {
62
+ return { reference: { root: root, transaction: transaction } };
63
63
  };
64
64
 
65
65
  it('An array of zero transactions should be valid', () => {
@@ -71,11 +71,11 @@ describe('When validating transaction references', () => {
71
71
  });
72
72
 
73
73
  it('An array with distinct references should be valid', () => {
74
- expect(TransactionValidator.validateReferences([ build('a', 1), build('a', 2), build('b', 1) ])).toEqual(true);
74
+ expect(TransactionValidator.validateReferences([ build('a', 'x'), build('a', 'y'), build('b', 'y') ])).toEqual(true);
75
75
  });
76
76
 
77
77
  it('An array with non-distinct references should be not valid', () => {
78
- expect(TransactionValidator.validateReferences([ build('a', 1), build('a', 2), build('b', 1), build('a', 2) ])).toEqual(false);
78
+ expect(TransactionValidator.validateReferences([ build('a', 'x'), build('a', 'y'), build('b', 'x'), build('a', 'y') ])).toEqual(false);
79
79
  });
80
80
  });
81
81