Skip to content

Commit feb9a6a

Browse files
Merge pull request #34 from bchainhub/update/feature-download-05
Downloads and tests
2 parents 93d94e1 + 4b557a5 commit feb9a6a

File tree

8 files changed

+442
-184
lines changed

8 files changed

+442
-184
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
.output
55
/build
66
/dist
7+
/test/output
78

89
# OS
910
.DS_Store

README.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ The library is designed to be compatible with both module systems, so you can ch
145145
- `getEndpoint(network?: number | string, countriesList?: string | Array<string>): { [key: string]: Array<string> }` — Get an object of SMS endpoints (phone numbers) per country.
146146
- `sms(number?: boolean | string | number | Array<string>, message?: string, network?: number | string, encodeMessage?: boolean, platform?: string): string` — Create an SMS URI based on the provided parameters.
147147
- `mms(number?: boolean | string | number | Array<string>, message?: string, network?: number | string, encodeMessage?: boolean, platform?: string): string` — Create an MMS URI based on the provided parameters.
148-
- `downloadMessage(hex: string | string[], optionalFilename?: string): Promise<string>` — Download a file with the encoded content as `.txms.txt` file in your working directory. You can provide one hex transaction or an array of transactions (`.batch` will be prepended to suffix if batch is chosen and optional name not defined).
148+
- `downloadMessage(hex: string | string[], optionalFilename?: string, optionalPath?: string): Promise<string>` — Download a file with the encoded content as `.txms.txt` file in your working directory. You can provide one hex transaction or an array of transactions (`.batch` will be prepended to suffix if batch is chosen and optional name not defined).
149149

150150
Note: The `downloadMessage` function is asynchronous and returns a Promise. You can use the `await` keyword to wait for the Promise to resolve. The function will download a file with the encoded content as a `(.batch).txms.txt` file in your working directory. You can optionally provide a filename as the second parameter. It is designed to be used in Node.js environments as well as Browser. It is not designed to download high amount of files. if you prefer to do your own download flow, you can use the `encode` function and save the result to a file.
151151

@@ -160,6 +160,7 @@ Note: The `downloadMessage` function is asynchronous and returns a Promise. You
160160
- `encodeMessage` (default: `true`) = whether to encode the message before using `encodeURIComponent`.
161161
- `platform` = the platform to use for the SMS URI. Currently supported: `ios`, `global`. Default: `global`. `ios` uses the `&body=`, while `global` uses the `?` for `?body=` parameter.
162162
- `optionalFilename` = the optional filename for the downloaded file suffixed with `.txms.txt`. Filename is slugified.
163+
- `optionalPath` = the optional path for the downloaded file. If not provided, the file will be saved in the working directory.
163164

164165
## CLI
165166

@@ -172,17 +173,23 @@ npm i -g txms.js
172173
### Getting started
173174

174175
```bash
175-
txms {type} {value} {value1}
176+
txms {type}={value}
176177
```
177178

178-
- type: `version` (`v`), `encode` (`e`), `decode` (`d`), `getendpoint` (`g`), `sms`, `mms`, `download` (`dl`)
179-
- value: 1st parameter for the type
180-
- value1: 2nd parameter for the type
179+
Types:
180+
181+
- `--version` (`-v`) - Get the version of the library.
182+
- `--encode` (`-e`) - Encode the HEX transaction.
183+
- `--decode` (`-d`) - Decode the UTF-16BE transaction.
184+
- `--getendpoint` (`-g`) - Get the SMS/MMS endpoint for the network and country.
185+
- `--sms` - Create an SMS URI based on the provided parameters.
186+
- `--mms` - Create an MMS URI based on the provided parameters.
187+
- `--download` (`-dl`) - Boolean value to download a file with the encoded content as `.txms.txt` file in your working directory.
181188

182189
### Piping
183190

184191
```bash
185-
echo {value} | txms {type} {value1}
192+
echo {value} | txms {type}={value1}
186193
```
187194

188195
## Extending Aliases and Countries

bin/txms

Lines changed: 157 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,122 @@
11
#!/usr/bin/env node
22

3+
import { mkdirSync, readFileSync, existsSync } from 'fs';
4+
import { fileURLToPath } from 'url';
5+
import path from 'path';
36
import txms from '../dist/index.js';
47

5-
if (process.stdin.isTTY) {
6-
const typ = process.argv[2];
7-
const value = process.argv[3];
8-
const value1 = process.argv[4];
8+
const __filename = fileURLToPath(import.meta.url);
9+
const __dirname = path.dirname(__filename);
10+
11+
// Helper function to parse command-line arguments with key-value pairs
12+
function parseArgs(argv) {
13+
const args = {
14+
kind: null, // The type of operation to perform
15+
value: null, // This will hold the hex data for encode/decode
16+
output: null, // For download output directory
17+
filename: null, // For download filename
18+
countryCodes: null, // For getEndpoint
19+
phoneNumbers: null, // For SMS/MMS phone numbers
20+
download: false, // Flag to indicate download
21+
};
22+
23+
argv.forEach((arg) => {
24+
if (arg.startsWith('--')) {
25+
const [key, value] = arg.split('=');
26+
switch (key) {
27+
case '--version':
28+
args.kind = 'version';
29+
break;
30+
case '--encode':
31+
args.kind = 'encode';
32+
args.value = value;
33+
break;
34+
case '--decode':
35+
args.kind = 'decode';
36+
args.value = value;
37+
break;
38+
case '--getendpoint':
39+
args.kind = 'getendpoint';
40+
args.value = value; // Network type for getEndpoint
41+
break;
42+
case '--sms':
43+
args.kind = 'sms';
44+
args.phoneNumbers = value; // Comma-separated phone numbers
45+
break;
46+
case '--mms':
47+
args.kind = 'mms';
48+
args.phoneNumbers = value; // Comma-separated phone numbers
49+
break;
50+
case '--download':
51+
args.download = true;
52+
break;
53+
case '--output':
54+
args.output = value;
55+
break;
56+
case '--filename':
57+
args.filename = value;
58+
break;
59+
case '--countries':
60+
args.countryCodes = value.split(','); // Comma-separated country codes
61+
break;
62+
default:
63+
break;
64+
}
65+
} else if (arg.startsWith('-')) {
66+
const [key, value] = arg.split('=');
67+
switch (key) {
68+
case '-v':
69+
args.kind = 'version';
70+
break;
71+
case '-e':
72+
args.kind = 'encode';
73+
args.value = value;
74+
break;
75+
case '-d':
76+
args.kind = 'decode';
77+
args.value = value;
78+
break;
79+
case '-g':
80+
args.kind = 'getendpoint';
81+
args.value = value;
82+
break;
83+
case '-s':
84+
args.kind = 'sms';
85+
args.phoneNumbers = value;
86+
break;
87+
case '-m':
88+
args.kind = 'mms';
89+
args.phoneNumbers = value;
90+
break;
91+
case '-o':
92+
args.output = value;
93+
break;
94+
case '-f':
95+
args.filename = value;
96+
break;
97+
case '-c':
98+
args.countryCodes = value.split(',');
99+
break;
100+
default:
101+
break;
102+
}
103+
} else {
104+
if (!args.value) {
105+
args.value = arg;
106+
}
107+
}
108+
});
109+
return args;
110+
}
9111

10-
run(typ, value, value1);
112+
// Parse the arguments
113+
const args = parseArgs(process.argv.slice(2));
114+
115+
if (process.stdin.isTTY) {
116+
// If the script is run with a TTY, process the command-line arguments
117+
run(args.kind, args.value, args.output, args.countryCodes, args.phoneNumbers, args.download, args.filename);
11118
} else {
119+
// If data is being piped into the script, capture it
12120
let content = '';
13121
process.stdin.setEncoding('utf8');
14122
process.stdin.on('data', (buf) => {
@@ -17,59 +125,65 @@ if (process.stdin.isTTY) {
17125
process.stdin.on('end', () => {
18126
content = content.trim();
19127

20-
let value = content;
21-
let typ = process.argv[2];
22-
let value1 = process.argv[3];
23-
24128
if (!content) {
25-
value = process.argv[2];
26-
typ = process.argv[3];
27-
value1 = process.argv[4];
129+
run(args.kind, args.value, args.output, args.countryCodes, args.phoneNumbers, args.download, args.filename);
130+
} else {
131+
run(args.kind, content, args.output, args.countryCodes, args.phoneNumbers, args.download, args.filename);
28132
}
29-
30-
run(typ, value, value1);
31133
});
32134
}
33135

34-
function run(typ, value, value1) {
35-
if (!value) {
36-
process.stderr.write('value is required\n');
136+
async function run(kind, value, output, countryCodes, phoneNumbers, download, filename) {
137+
if (!value && kind !== 'version') {
138+
process.stderr.write('Value is required\n');
37139
process.exit(1);
38140
}
39141

40142
try {
41-
if (typ === 'version' || typ === 'v') {
42-
const packageJsonPath = join(__dirname, '../package.json');
143+
if (download && output && !existsSync(output)) {
144+
mkdirSync(output, { recursive: true });
145+
}
146+
147+
if (kind === 'version' || kind === 'v') {
148+
const packageJsonPath = path.join(__dirname, '../package.json');
43149
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
44150
const version = packageJson.version;
45-
process.stdout.write(`TxMS version: ${version}\n`);
46-
} else if (typ === 'encode' || typ === 'e') {
47-
const encoded = txms.encode(value);
48-
process.stdout.write(`${encoded}\n`);
49-
} else if (typ === 'decode' || typ === 'd') {
151+
process.stdout.write(version);
152+
process.exit(0);
153+
} else if (kind === 'encode' || kind === 'e') {
154+
if (download) {
155+
const filenm = await txms.downloadMessage(value, filename ? filename : undefined, output);
156+
process.stdout.write(`TxMS file was downloaded as "${filenm}".\n`);
157+
} else {
158+
const encoded = txms.encode(value);
159+
process.stdout.write(encoded);
160+
}
161+
process.exit(0);
162+
} else if (kind === 'decode' || kind === 'd') {
50163
const decoded = txms.decode(value);
51-
process.stdout.write(`${decoded}\n`);
52-
} else if (typ === 'getendpoint' || typ === 'g') {
53-
const endpoint = txms.getEndpoint(value, value1);
54-
process.stdout.write(`${JSON.stringify(endpoint, null, 2)}\n`);
55-
} else if (typ === 'sms') {
56-
const sms = txms.sms(true, value);
57-
process.stdout.write(`${sms}\n`);
58-
} else if (typ === 'mms') {
59-
const mms = txms.mms(true, value);
60-
process.stdout.write(`${mms}\n`);
61-
} else if (typ === 'download' || typ === 'dl') {
62-
txms.downloadMessage(value, value1).then((filename) => {
63-
process.stdout.write(`TxMS file was downloaded as "${filename}" in your working directory.\n`);
64-
process.exit(0);
65-
}).catch((err) => {
66-
process.stderr.write(`${err.message}\n`);
67-
process.exit(1);
68-
});
164+
process.stdout.write(decoded);
165+
process.exit(0);
166+
} else if (kind === 'getendpoint' || kind === 'g') {
167+
const endpoint = txms.getEndpoint(value, countryCodes);
168+
let endpointString = Object.keys(endpoint).map(key => {
169+
const numbers = endpoint[key].join(',');
170+
return `${key}:${numbers}`;
171+
}).join(';');
172+
process.stdout.write(endpointString);
173+
process.exit(0);
174+
} else if (kind === 'sms') {
175+
const message = txms.encode(value);
176+
const sms = txms.sms(phoneNumbers ? phoneNumbers.split(',') : true, message);
177+
process.stdout.write(sms);
178+
process.exit(0);
179+
} else if (kind === 'mms') {
180+
const message = txms.encode(value);
181+
const mms = txms.mms(phoneNumbers ? phoneNumbers.split(',') : true, message);
182+
process.stdout.write(mms);
183+
process.exit(0);
69184
} else {
70185
throw new Error('Invalid type specified.');
71186
}
72-
process.exit(0);
73187
} catch (err) {
74188
process.stderr.write(`${err.message}\n`);
75189
process.exit(1);

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "txms.js",
3-
"version": "1.2.7",
3+
"version": "1.2.8",
44
"description": "Transaction messaging service protocol",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
@@ -12,7 +12,7 @@
1212
"build": "tsc -p ./tsconfig.json",
1313
"test": "npm run unit",
1414
"preunit": "npm run build",
15-
"unit": "tape test/*.js",
15+
"unit": "node --test",
1616
"lint": "eslint 'src/**/*.{js,ts}' --fix"
1717
},
1818
"engines": {
@@ -46,11 +46,11 @@
4646
"author": "@bchainhub",
4747
"license": "CORE",
4848
"devDependencies": {
49-
"@types/node": "^22.3.0",
50-
"@typescript-eslint/eslint-plugin": "^8.1.0",
51-
"@typescript-eslint/parser": "^8.1.0",
52-
"eslint": "^9.9.0",
53-
"tape": "^5.8.1",
49+
"@types/node": "^22.5.1",
50+
"@typescript-eslint/eslint-plugin": "^8.3.0",
51+
"@typescript-eslint/parser": "^8.3.0",
52+
"eslint": "^9.9.1",
53+
"jsdom": "^25.0.0",
5454
"typescript": "^5.5.4"
5555
}
5656
}

0 commit comments

Comments
 (0)