rxome-generator 0.1.1 → 0.1.4

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/README.md CHANGED
@@ -1,10 +1,11 @@
1
- # rxome-qrcode-generator
2
- Generates QR codes containing medical information for use with the RxOME database.
3
- **Right now, it works only with the test API**
1
+ # FindMe2Care (RxOME) QR-code generator
2
+ Generates QR codes containing medical information for use with the FindMe2Care database
3
+ (formerly called RxOME).
4
+ **Right now, it works only with the test API (-t, Coder.TESTAPI)**
4
5
 
5
6
  ## LICENSE
6
7
 
7
- Copyright (c) 2022 MGZ-Tech GmbH, GeneTalk GmbH
8
+ Copyright (c) 2022 MGZ-Tech GmbH
8
9
 
9
10
  All rights reserved, unauthorized use prohibited.
10
11
 
@@ -32,14 +33,19 @@ In case the patient already has a pseudonym that will be used for the QR code,
32
33
  the known pseudonym can be specified in the MetaData section of the input JSON data.
33
34
  Additionally, the command line tool
34
35
  offers a command line argument, `-p`, for specifying a known pseudonym.
36
+ Note that this pseudonym must be a valid RxOME pseudonym, that is, it has to be generated by
37
+ RxOME for a previous medical statement. Using an arbitrary pseudonym will render the
38
+ generated QR-Code useless, as it cannot be processed by RxOME.
35
39
 
36
40
  By default, the keywords in the JSON file are expected to be noted in camelCase. However, the tool
37
41
  can convert snake_case to camelCase (command line: -s, library: function convertToCamelCase).
38
42
 
43
+ ## Installation
44
+ > `npm install rxome-generator`
39
45
 
40
46
  ## Basic Usage
41
47
 
42
- ###Command Line Tool
48
+ ### Command Line Tool
43
49
 
44
50
  Generate a QR code *inputfile*.png from a JSON file *inputfile*.json containing all medical data in PhenoPacket format, meta data and credentials (using camelCase for keywords):
45
51
 
@@ -48,7 +54,7 @@ Generate a QR code *inputfile*.png from a JSON file *inputfile*.json containing
48
54
  For detailed descriptions see
49
55
  > `rxcode g --help`
50
56
 
51
- ###Library Functions
57
+ ### Library Functions
52
58
  Import the library with
53
59
  > `const Coder = require( 'rxome-generator' );`
54
60
 
@@ -101,7 +107,8 @@ Pleace specify *either* a file containing the API access key (keyFile, -k)
101
107
  *or* the key itself (key, -s).
102
108
 
103
109
  When a pseudonym is given (either in the meta data or with command line option `-P`),
104
- the QR code will be generated using this pseudonym. Otherwise, a new one will be
110
+ the QR code will be generated using this pseudonym (this must be a valid/known RxOME
111
+ pseudonym, see introduction). Otherwise, a new one will be
105
112
  fetched from the server. In both cases, the
106
113
  pseudonym used will be part of the output for futher processing or storing.
107
114
 
@@ -110,7 +117,7 @@ pseudonym used will be part of the output for futher processing or storing.
110
117
  ...
111
118
  metaData: {
112
119
  ...
113
- pseudonym: 'anonymous'
120
+ pseudonym: '19T5K7042'
114
121
  }
115
122
  credentials: {
116
123
  keyId: <lab-id/key-id, corresponding to private key>
@@ -179,20 +186,21 @@ The type of genetic test performed to obtain a variant can be specified in an ex
179
186
  "acmgPathogenicityClassification": "Pathogenic",
180
187
  "variationDescriptor": {
181
188
  "geneContext": {
182
- "expressions": [
183
- {
184
- "syntax": "hgvs.c",
185
- "value": "NM_017837.4(PIGV):c.1022C>A (p.Ala341Glu)"
186
- }
187
- ],
188
- "allelicState": {
189
- "id": "GENO_0000136"
190
- },
191
- "extensions": [
192
- {
193
- "name": "Single gene sequencing"
194
- }
195
- ]
189
+ "expressions": [
190
+ {
191
+ "syntax": "hgvs.c",
192
+ "value": "NM_017837.4(PIGV):c.1022C>A (p.Ala341Glu)"
193
+ }
194
+ ],
195
+ "allelicState": {
196
+ "id": "GENO_0000136"
197
+ },
198
+ "extensions": [
199
+ {
200
+ "name": "Single gene sequencing"
201
+ }
202
+ ]
203
+ }
196
204
  }
197
205
  }
198
206
  }
@@ -289,7 +297,7 @@ Options:
289
297
  -u, --user <user string> API access user (default: credentials.user
290
298
  or metaData.submittedBy or info@rxome.net)
291
299
  -c, --created <date> Date (default: input file, metaData.created)
292
- -l, --lab <lab> Laboratory name (default: input file, metaData.createdBy)
300
+ -l, --lab <lab> Laboratory name (default: input file, metaData.createdBy or lab name stored in the user account)
293
301
  -e, --email <email> Laboratory email (default: input file, metaData.submittedBy)
294
302
  -S, --snake Read payload formatted in snake_case (default: camelCase)
295
303
  -t, --test Use test API instead of production API
@@ -319,6 +327,11 @@ rxcode g -t -o qrcode.png demos/demo_data_full.json
319
327
 
320
328
  <img src="qrcode.png" width="400">
321
329
 
330
+ ## Testing
331
+ Codes generated by the test API (i.e., with the `-t` switch or `API=Coder.TESTAPI`) can be decoded online using the following tool:
332
+
333
+ Todo: URL Code-Reader Demo
334
+
322
335
  ## Debugging
323
336
  To check the connection to the API on RxOME server API use
324
337
 
@@ -0,0 +1,100 @@
1
+ "subject": {
2
+ "id": "proband A",
3
+ "dateOfBirth": "1994-01-01T00:00:00Z",
4
+ "sex": "FEMALE"
5
+ },
6
+ "phenotypicFeatures":
7
+ [HPOin]
8
+ HP:0030084
9
+ HP:0000555
10
+ HP:0000486
11
+ HP:0000541
12
+ HP:0084369
13
+ HP:0112358
14
+ HP:0000145
15
+ HP:1234567
16
+ HP:9876543
17
+ HP:5678912
18
+
19
+ [HPOex]
20
+ HP:0031360
21
+ HP:0001234
22
+
23
+ "interpretations": [
24
+ {
25
+ "id": "interpretation.id",
26
+ "progressStatus": "SOLVED",
27
+ "diagnosis": {
28
+ "disease": {
29
+ "id": "OMIM:263750"
30
+ },
31
+ "genomicInterpretations": [
32
+ {
33
+ "variantInterpretation": {
34
+ "acmgPathogenicityClassification": "PATHOGENIC",
35
+ "variationDescriptor": {
36
+ "geneContext": {
37
+ "valueId": "HGNC:9884",
38
+ "symbol": "RB1"
39
+ },
40
+ "expressions": [
41
+ {
42
+ "syntax": "hgvs.c",
43
+ "value": "NM_000321.2:c.958C>T"
44
+ }
45
+ ],
46
+ "allelicState": {
47
+ "id": "GENO:0000135"
48
+ },
49
+ "extensions": [
50
+ {
51
+ "name": "test-type",
52
+ "value": "Exome, short read"
53
+ }
54
+ ]
55
+ }
56
+ }
57
+ },
58
+ {
59
+ "variantInterpretation": {
60
+ "acmgPathogenicityClassification": "LIKELY_PATHOGENIC",
61
+ "variationDescriptor": {
62
+ "geneContext": {
63
+ "valueId": "HGNC:9884",
64
+ "symbol": "RB1"
65
+ },
66
+ "expressions": [
67
+ {
68
+ "syntax": "hgvs.c",
69
+ "value": "NM_000321.2:c.1234A>G"
70
+ }
71
+ ],
72
+ "allelicState": {
73
+ "label": "heterozygous"
74
+ },
75
+ "extensions": [
76
+ {
77
+ "name": "test-type",
78
+ "value": "Exome, short read"
79
+ }
80
+ ]
81
+ }
82
+ }
83
+ }
84
+ ]
85
+ }
86
+ }
87
+ ],
88
+ "metaData": {
89
+ "created": "2021-05-14T10:35:00Z",
90
+ "createdBy": "mgz",
91
+ "submittedBy": "a_clinician@mgz-muenchen.de",
92
+ "phenopacketSchemaVersion": "2.0",
93
+ "pseudonym": "_DEMO_PSEUDONYM_"
94
+ },
95
+ "credentials": {
96
+ "key": "lBSkSxe/+UBWOeF5OJdQgf9qZhiI85hYE6yJCuWjCNk=",
97
+ "keyId": "rxome",
98
+ "user": "a_clinician@mgz-muenchen.de"
99
+ }
100
+ }
package/index.js CHANGED
@@ -1,3 +1,3 @@
1
- export * from './lib/rxome-api';
2
- export * from './lib/rxome-api-demo';
3
- export * from './lib/rxome-generator';
1
+ export * from './lib/rxome-api.cjs';
2
+ export * from './lib/rxome-api-demo.cjs';
3
+ export * from './lib/rxome-generator.cjs';
@@ -4,8 +4,8 @@ const Protobuf = require('protobufjs');
4
4
  const { stringify } = require('querystring');
5
5
  //const BASE64 = require('@protobufjs/base64')
6
6
 
7
- const API = 'https://www.rxome.net';
8
- const TESTAPI = 'http://stage.rxome.net';
7
+ const API = 'https://app.findme2care.de';
8
+ const TESTAPI = 'https://stage.findme2care.de';
9
9
  const APIENTRY = 'api/v1';
10
10
  const VSTR = 'API1.0'
11
11
  const IS_DEMO = '_DEMO_PSEUDONYM_';
@@ -74,6 +74,8 @@ catch (e) {
74
74
  }
75
75
  }
76
76
 
77
+ exports.readSigKey = readSigKey;
78
+
77
79
  /************************************************************************************/
78
80
 
79
81
  exports.signData = async( keyId, user, keyB64, created, debug = false ) => {
@@ -10,7 +10,7 @@ const PhenoPacketDescriptor = require("./phenopackets.json");
10
10
 
11
11
  //const { constants } = require('buffer');
12
12
 
13
- const RxAPI= require('./rxome-api');
13
+ const RxAPI= require('./rxome-api.cjs');
14
14
 
15
15
  const apiVer = '1.0';
16
16
  const RXAPI = RxAPI.API;
@@ -55,7 +55,7 @@ try {
55
55
  const {qrData, pseudonym} = await exports.prepareQR( data, api, apiEntry );
56
56
  //const base64Data = qr_code.replace(/^data:image\/png;base64,/, "");
57
57
  //FS.writeFile(filename, base64Data, 'base64', (err) => {console.log(err)} );
58
- QRCode.toFile( filename, qrData, { type: 'png'} )
58
+ QRCode.toFile( filename, JSON.stringify( qrData ), { type: 'png'} )
59
59
  return pseudonym
60
60
  }
61
61
  }
@@ -291,13 +291,12 @@ exports.prepareQR = async ( data, api = RXAPI, apiEntry = APIENTRY ) => {
291
291
  const key = await this.fetchKey( credentials, metaData.pseudonym || '', api, false, apiEntry );
292
292
 
293
293
  // check:
294
- const buff = RxAPI.base64ToBuffer( base64Medical );
295
- const pheno = exports.decodePhenoPacket( buff );
294
+ //const buff = RxAPI.base64ToBuffer( base64Medical );
295
+ //const pheno = exports.decodePhenoPacket( buff );
296
296
  //const medicalDeciphered = JSON.parse( JSON.stringify( pheno ));
297
297
  //console.log( JSON.stringify(medicalDeciphered,' ', 2 ))
298
298
 
299
299
  const cipher = await exports.encode( key.key, base64Medical );
300
- //console.log( 'Cipher:', JSON.stringify(cipher) );
301
300
 
302
301
  //delete metaData.pseudonym;
303
302
  const newMetaData = Object.fromEntries(
@@ -305,17 +304,18 @@ exports.prepareQR = async ( data, api = RXAPI, apiEntry = APIENTRY ) => {
305
304
  )
306
305
 
307
306
  const qrData = {
307
+ createdBy: key.lab,
308
308
  ...newMetaData,
309
+ labid: key.lab_id,
309
310
  keyver: key.version,
310
311
  apiver: apiVer,
311
312
  pseudonym: key.pseudonym,
312
313
  payload: cipher.toString()
313
314
  }
314
- // console.log( qrData );
315
- // console.log( "QR-Data " , JSON.stringify( qrData ).length );
315
+ console.log( "[QR Generator lib ]", qrData, "\nLength: ", JSON.stringify( qrData ).length );
316
316
 
317
317
  return {
318
- qrData: JSON.stringify( qrData ),
318
+ qrData: qrData,
319
319
  pseudonym: key.pseudonym
320
320
  }
321
321
  }
@@ -324,7 +324,7 @@ exports.prepareQR = async ( data, api = RXAPI, apiEntry = APIENTRY ) => {
324
324
  exports.makeQR = async ( data, api = RXAPI, apiEntry = APIENTRY ) => {
325
325
  const {qrData, pseudonym} = await exports.prepareQR( data, api, apiEntry );
326
326
  return {
327
- qr_code: await QRCode.toDataURL( qrData ),
327
+ qr_code: await QRCode.toDataURL( JSON.stringify( qrData )),
328
328
  pseudonym: pseudonym,
329
329
  qr_data: qrData
330
330
  }
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "rxome-generator",
3
- "version": "0.1.1",
3
+ "version": "0.1.4",
4
4
  "description": "Generates QR codes containing medical information for use with RxOME database.",
5
5
  "main": "index.js",
6
- "type": "commonjs",
6
+ "type": "module",
7
7
  "scripts": {
8
8
  "test": "jest --verbose",
9
9
  "testcoder": "jest --verbose -t 'Coder'",
@@ -24,7 +24,6 @@
24
24
  "phenopacket"
25
25
  ],
26
26
  "author": "Tom Kamphans",
27
- "license": "MIT",
28
27
  "license" : "SEE LICENSE IN README.md",
29
28
  "bugs": {
30
29
  "url": "https://github.com/GeneTalkTK/rxome-qrcode-generator/issues"
@@ -1,13 +1,24 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const Coder = require( './lib/rxome-generator' );
4
- const ApiDemo = require( './lib/rxome-api-demo' );
5
- const RxAPI = require( './lib/rxome-api' );
6
- const { program } = require('commander');
7
-
8
- const FS = require( 'fs' );
9
- const Path = require('path');
10
- const { cp } = require('fs/promises');
3
+ import * as FS from 'fs';
4
+ // const Coder = require( './lib/rxome-generator' );
5
+ import * as Coder from './lib/rxome-generator.cjs';
6
+ import * as ApiDemo from './lib/rxome-api-demo.cjs' ;
7
+ import * as RxAPI from './lib/rxome-api.cjs';
8
+
9
+ import { program } from 'commander';
10
+ import * as Path from 'path';
11
+ // import { cp } from 'fs/promises';
12
+
13
+ // const FS = require( 'fs' );
14
+ // const Coder = require( './lib/rxome-generator' );
15
+ // const ApiDemo = require( './lib/rxome-api-demo' );
16
+ // const RxAPI = require( './lib/rxome-api' );
17
+ // const { program } = require('commander');
18
+
19
+ // const Path = require('path');
20
+ // const { cp } = require('fs/promises');
21
+
11
22
  //const TXT = require( './assets/scripts/modules/texte.js')
12
23
 
13
24
  const DEMO_CREDENTIALS = ApiDemo.DEMO_CREDENTIALS
@@ -42,7 +53,7 @@ Output: prints the given or new pseudonym.`)
42
53
  .option('-s, --key <key string>', 'API access key (default: input file, credentials.key)')
43
54
  .option('-u, --user <user string>', 'API access user (default: credentials.user or metaData.submittedBy or info@rxome.net)')
44
55
  .option('-c, --created <date>', 'Date (default: input file, metaData.created)')
45
- .option('-l, --lab <lab>', 'Laboratory name (default: input file, metaData.createdBy)')
56
+ .option('-l, --lab <lab>', 'Laboratory name (default: input file, metaData.createdBy or lab name stored in the user account)')
46
57
  .option('-e, --email <email>', 'Laboratory email (default: input file, metaData.submittedBy)')
47
58
  .option('-S, --snake', 'Read payload formatted in snake_case (default: camelCase)')
48
59
  .option('-t, --test', 'Use test API instead of production API')
@@ -119,7 +130,7 @@ program.command('preprocess')
119
130
  .option('-o, --output <output file>', 'Output JSON file (default: stdout)')
120
131
  .option('-C, --case', 'Apply case style converter from snake_case to camelCase')
121
132
  .option('-w, --whitelist', 'Apply whitelist filtering (remove unnecessary sections)')
122
- .option('-s, --sanitize', 'A pply sanitizing step (remove common mistakes)')
133
+ .option('-s, --sanitize', 'Apply sanitizing step (remove common mistakes)')
123
134
  .option('-c, --compress', 'Compact HPO term list')
124
135
  .action( async (inputfile, options) => {
125
136
  let data = JSON.parse(FS.readFileSync( inputfile || '/dev/stdin' ));
@@ -160,7 +171,7 @@ program.command('apikeys')
160
171
  program.command('ping')
161
172
  .summary('Ping API/check API credentials')
162
173
  .alias('P')
163
- .argument('[id]', 'API access key ID (default: rxome)')
174
+ .argument('id', 'API access key ID')
164
175
  .argument('key', 'API access key')
165
176
  .option('-t, --test', 'Connect to test API')
166
177
  .option('-L, --localhost', 'Connect to localhost API')
package/rxcode.test.js CHANGED
@@ -42,7 +42,9 @@ async function execCmd( cmd ) {
42
42
 
43
43
  describe('CmdLine generate', () => {
44
44
  test('generates a qr code from demo data', () => {
45
- FS.rmSync( '__TESTSUITE_IMG.png' );
45
+ if ( FS.existsSync( '__TESTSUITE_IMG.png' )) {
46
+ FS.rmSync( '__TESTSUITE_IMG.png' );
47
+ }
46
48
  execCmd( 'rxcode g -t -o __TESTSUITE_IMG.png demos/demo_data_full.json' )
47
49
  // execCmd( 'rxcode g -L -o __TESTSUITE_IMG.png demos/demo_data_full.json' )
48
50
  .then( res => {
@@ -189,4 +191,4 @@ rxcode d -j rxome.decrypt.json
189
191
  rxcode d -j rxome.decrypt.json
190
192
  rxcode d -j < rxome.decrypt
191
193
 
192
- */
194
+ */
@@ -1,17 +0,0 @@
1
- -----BEGIN PGP PRIVATE KEY BLOCK-----
2
-
3
- xYYEY8BGEhYJKwYBBAHaRw8BAQdAegfXQCYheo+FJXoIY0qPYAeP+67inq0u
4
- 0AZE8yrEOJ3+CQMIQ3S9CuD3PUTgKF/q8xafzIvLlEuLTCAInll8oSg9zb+2
5
- MTFp3EEOZifKIA9YY1ujro17MzR3p/Bfdt2ayo+Pcxq0g9JNgrHfzUeIuTxG
6
- xM0VZGVtbyA8aW5mb0ByeG9tZS5uZXQ+wowEEBYKAB0FAmPARhIECwkHCAMV
7
- CAoEFgACAQIZAQIbAwIeAQAhCRABSM3I8Z0TohYhBGfCy2DdehZ+Frs2fgFI
8
- zcjxnROi9ukA/RmZoF4VKDJouTjxPxCEzIqbM+9ZfHFyLmkr9EtMR0D+AP9o
9
- 5Rauo9ium/t88qxfeCpcPTULZ4qu5GBkBHg9XCYrAceLBGPARhISCisGAQQB
10
- l1UBBQEBB0A82B97nnZ60gGWR2v8mn319Yb8AdKGD85ier7hwSe/OgMBCAf+
11
- CQMIUzDpTTSoyZrg8AVwyRZVmrXQbE9mzRtcy2sM3fbNyZCW44Rz0rgxwC+z
12
- 1EfRC442wQSDs6pat0eeBX1Eh6vqENIRsCQNK426BD8XWWLor8J4BBgWCAAJ
13
- BQJjwEYSAhsMACEJEAFIzcjxnROiFiEEZ8LLYN16Fn4WuzZ+AUjNyPGdE6In
14
- sAD9GNlDrmnRIz+IP0XGheue6IhMLgzss2TsvRv2K8HQGqsBAIC3k3/T/sCN
15
- MnR+TVPz/zYEEAbxEEurgfWdn1c8B0AM
16
- =Sgm6
17
- -----END PGP PRIVATE KEY BLOCK-----
@@ -1,13 +0,0 @@
1
- -----BEGIN PGP PUBLIC KEY BLOCK-----
2
-
3
- xjMEY8BGEhYJKwYBBAHaRw8BAQdAegfXQCYheo+FJXoIY0qPYAeP+67inq0u
4
- 0AZE8yrEOJ3NFWRlbW8gPGluZm9AcnhvbWUubmV0PsKMBBAWCgAdBQJjwEYS
5
- BAsJBwgDFQgKBBYAAgECGQECGwMCHgEAIQkQAUjNyPGdE6IWIQRnwstg3XoW
6
- fha7Nn4BSM3I8Z0TovbpAP0ZmaBeFSgyaLk48T8QhMyKmzPvWXxxci5pK/RL
7
- TEdA/gD/aOUWrqPYrpv7fPKsX3gqXD01C2eKruRgZAR4PVwmKwHOOARjwEYS
8
- EgorBgEEAZdVAQUBAQdAPNgfe552etIBlkdr/Jp99fWG/AHShg/OYnq+4cEn
9
- vzoDAQgHwngEGBYIAAkFAmPARhICGwwAIQkQAUjNyPGdE6IWIQRnwstg3XoW
10
- fha7Nn4BSM3I8Z0ToiewAP0Y2UOuadEjP4g/RcaF657oiEwuDOyzZOy9G/Yr
11
- wdAaqwEAgLeTf9P+wI0ydH5NU/P/NgQQBvEQS6uB9Z2fVzwHQAw=
12
- =w+2C
13
- -----END PGP PUBLIC KEY BLOCK-----
File without changes