Skip to content

Commit eb533ab

Browse files
committed
convert x509 sample to ts
1 parent 4ba3397 commit eb533ab

4 files changed

Lines changed: 151 additions & 37 deletions

File tree

samples/node/mqtt/mqtt5_x509/README.md

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# MQTT5 X509 PubSub
1+
# MQTT5 X509 PubSub - TypeScript
22

33
[**Return to main sample list**](../../README.md)
44

@@ -13,6 +13,8 @@ This sample uses the
1313
[Message Broker](https://docs.aws.amazon.com/iot/latest/developerguide/iot-message-broker.html)
1414
for AWS IoT to send and receive messages through an MQTT connection using MQTT5.
1515

16+
This is the **TypeScript version** of the JavaScript sample found in `samples/node/mqtt/mqtt5_x509`.
17+
1618
You can read more about MQTT5 for the JavaScript IoT Device SDK V2 in the [MQTT5 user guide](https://github.com/awslabs/aws-crt-nodejs/blob/main/MQTT5-UserGuide.md).
1719

1820
## Requirements
@@ -69,37 +71,68 @@ Note that in a real application, you may want to avoid the use of wildcards in y
6971

7072
## How to run
7173

72-
To Run this sample from the `samples/node/mqtt/mqtt5_x509` folder, use the following command:
74+
### Prerequisites
75+
- Node.js v14+
76+
- TypeScript (installed as dev dependency)
77+
78+
### Installation and Running
79+
80+
To run this sample from the `samples/node/mqtt/mqtt5_x509_ts` folder:
7381

82+
1. Install dependencies:
7483
```sh
7584
npm install
76-
node index.js \
85+
```
86+
87+
2. Run using npm script (builds and runs):
88+
```sh
89+
npm start -- \
7790
--endpoint <AWS IoT endpoint> \
7891
--cert <Path to certificate file> \
7992
--key <Path to private key file>
8093
```
81-
If you would like to see what optional arguments are available, use the `--help` argument:
82-
``` sh
83-
node index.js --help
94+
95+
3. Or build and run manually:
96+
```sh
97+
npm run build
98+
node dist/index.js \
99+
--endpoint <AWS IoT endpoint> \
100+
--cert <Path to certificate file> \
101+
--key <Path to private key file>
84102
```
85103

86-
will result in the following output:
104+
4. For development with ts-node:
105+
```sh
106+
npm run dev -- \
107+
--endpoint <AWS IoT endpoint> \
108+
--cert <Path to certificate file> \
109+
--key <Path to private key file>
87110
```
88-
Options:
89-
--version Show version number [boolean]
90-
-e, --endpoint IoT endpoint hostname [string] [required]
91-
-c, --cert Path to the certificate file to use during mTLS connection
92-
establishment [string] [required]
93-
-k, --key Path to the private key file to use during mTLS connection
94-
establishment [string] [required]
95-
-C, --client_id Client ID [string] [default: "mqtt5-sample-1e2e1bef"]
96-
-t, --topic Topic [string] [default: "test/topic"]
97-
-m, --message Message payload [string] [default: "Hello from mqtt5 sample"]
98-
-n, --count Messages to publish (0 = infinite) [number] [default: 5]
99-
--help Show help [boolean]
111+
112+
### Command Line Options
113+
114+
If you would like to see what optional arguments are available, use the `--help` argument:
115+
```sh
116+
npm start -- --help
100117
```
101118

102-
The sample will not run without the required arguments and will notify you of missing arguments.
119+
This will show all available options including:
120+
- `--endpoint` (required): IoT endpoint hostname
121+
- `--cert` (required): Path to certificate file
122+
- `--key` (required): Path to private key file
123+
- `--client_id`: Client ID (default: auto-generated)
124+
- `--topic`: Topic name (default: "test/topic")
125+
- `--message`: Message payload (default: "Hello from mqtt5 sample")
126+
- `--count`: Number of messages to publish (default: 5, 0 = infinite)
127+
128+
## TypeScript Features
129+
130+
This TypeScript version includes:
131+
- **Type Safety**: Full TypeScript type annotations for better development experience
132+
- **Interface Definitions**: Proper typing for command line arguments
133+
- **Event Type Safety**: Typed event handlers for MQTT5 client events
134+
- **Build Process**: Compilation to JavaScript with source maps
135+
- **Development Mode**: Direct TypeScript execution with ts-node
103136

104137
## Additional Information
105138
Additional help with the MQTT5 Client can be found in the [MQTT5 Userguide](https://github.com/awslabs/aws-crt-nodejs/blob/main/MQTT5-UserGuide.md). This guide will provide more details on MQTT5 operations, lifecycle events, connection methods, and other useful information.
Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
* SPDX-License-Identifier: Apache-2.0.
44
*/
55

6-
const { mqtt5, iot } = require("aws-iot-device-sdk-v2");
7-
const { once } = require("events");
8-
const yargs = require('yargs');
9-
const { v4: uuidv4 } = require('uuid');
6+
import { mqtt5, iot } from "aws-iot-device-sdk-v2";
7+
import { once } from "events";
8+
import yargs from "yargs";
9+
import { v4 as uuidv4 } from "uuid";
1010

1111
const TIMEOUT = 100000;
1212

@@ -81,7 +81,7 @@ async function runSample() {
8181
const client = new mqtt5.Mqtt5Client(config);
8282

8383
// Event handler for when any message is received
84-
client.on('messageReceived', (eventData) => {
84+
client.on('messageReceived', (eventData: mqtt5.MessageReceivedEvent) => {
8585
const message = eventData.message;
8686
const payload = message.payload ? Buffer.from(message.payload).toString('utf-8') : '';
8787
console.log(`==== Received message from topic '${message.topicName}': ${payload} ====\n`);
@@ -103,17 +103,17 @@ async function runSample() {
103103
});
104104

105105
// Event handler for lifecycle event Connection Success
106-
client.on('connectionSuccess', (eventData) => {
106+
client.on('connectionSuccess', (eventData: mqtt5.ConnectionSuccessEvent) => {
107107
console.log(`Lifecycle Connection Success with reason code: ${eventData.connack.reasonCode}\n`);
108108
});
109109

110110
// Event handler for lifecycle event Connection Failure
111-
client.on('connectionFailure', (eventData) => {
111+
client.on('connectionFailure', (eventData: mqtt5.ConnectionFailureEvent) => {
112112
console.log(`Lifecycle Connection Failure with exception: ${eventData.error}`);
113113
});
114114

115115
// Event handler for lifecycle event Disconnection
116-
client.on('disconnection', (eventData) => {
116+
client.on('disconnection', (eventData: mqtt5.DisconnectionEvent) => {
117117
const reasonCode = eventData.disconnect ? eventData.disconnect.reasonCode : 'None';
118118
console.log(`Lifecycle Disconnected with reason code: ${reasonCode}`);
119119
});
@@ -127,7 +127,7 @@ async function runSample() {
127127
const connectionSuccess = once(client, "connectionSuccess");
128128
await Promise.race([
129129
connectionSuccess,
130-
new Promise((_, reject) => setTimeout(() => reject(new Error("Connection timeout")), TIMEOUT))
130+
new Promise<never>((_, reject) => setTimeout(() => reject(new Error("Connection timeout")), TIMEOUT))
131131
]);
132132

133133
console.log(`==== Subscribing to topic '${args.topic}' ====`);
@@ -156,17 +156,17 @@ async function runSample() {
156156
payload: message,
157157
qos: mqtt5.QoS.AtLeastOnce
158158
});
159-
console.log(`PubAck received with ${publishResult.reasonCode}\n`);
159+
console.log(`PubAck received with ${publishResult?.reasonCode}\n`);
160160

161-
await new Promise(resolve => setTimeout(resolve, 1500));
161+
await new Promise<void>(resolve => setTimeout(resolve, 1500));
162162
publishCount++;
163163
}
164164

165165
if (receivedCount < args.count) {
166166
const receivedAll = once(client, "receivedAll");
167167
await Promise.race([
168168
receivedAll,
169-
new Promise(resolve => setTimeout(resolve, 5000))
169+
new Promise<void>(resolve => setTimeout(resolve, 5000))
170170
]);
171171
}
172172
console.log(`${receivedCount} message(s) received.\n`);
@@ -184,7 +184,7 @@ async function runSample() {
184184

185185
await Promise.race([
186186
stopped,
187-
new Promise((_, reject) => setTimeout(() => reject(new Error("Stop timeout")), TIMEOUT))
187+
new Promise<never>((_, reject) => setTimeout(() => reject(new Error("Stop timeout")), TIMEOUT))
188188
]);
189189

190190
console.log("==== Client Stopped! ====");
@@ -193,7 +193,7 @@ async function runSample() {
193193

194194
runSample().then(() => {
195195
process.exit(0);
196-
}).catch((error) => {
196+
}).catch((error: Error) => {
197197
console.error(error);
198198
process.exit(1);
199199
});

samples/node/mqtt/mqtt5_x509/package.json

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,27 @@
22
"name": "mqtt5-x509-sample",
33
"version": "1.0.0",
44
"description": "MQTT5 X509 Sample (mTLS)",
5-
"main": "index.js",
5+
"homepage": "https://github.com/aws/aws-iot-device-sdk-js-v2",
6+
"repository": {
7+
"type": "git",
8+
"url": "git+https://github.com/aws/aws-iot-device-sdk-js-v2.git"
9+
},
10+
"contributors": [
11+
"AWS SDK Common Runtime Team <aws-sdk-common-runtime@amazon.com>"
12+
],
13+
"license": "Apache-2.0",
14+
"main": "dist/index.js",
615
"scripts": {
7-
"start": "node index.js"
16+
"tsc": "tsc",
17+
"prepare": "npm run tsc"
818
},
919
"dependencies": {
1020
"aws-iot-device-sdk-v2": "file:../../../..",
11-
"yargs": "^17.0.0",
21+
"yargs": "^16.2.0",
1222
"uuid": "^9.0.0"
23+
},
24+
"devDependencies": {
25+
"@types/node": "10.17.50",
26+
"typescript": "^4.7.4"
1327
}
1428
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
{
2+
"compilerOptions": {
3+
/* Basic Options */
4+
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
5+
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
6+
"declaration": true, /* Generates corresponding '.d.ts' file. */
7+
"sourceMap": true, /* Generates corresponding '.map' file. */
8+
"outDir": "./dist", /* Redirect output structure to the directory. */
9+
// "lib": [], /* Specify library files to be included in the compilation. */
10+
// "allowJs": true, /* Allow javascript files to be compiled. */
11+
// "checkJs": true, /* Report errors in .js files. */
12+
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
13+
// "outFile": "./", /* Concatenate and emit output to single file. */
14+
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
15+
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
16+
// "composite": true, /* Enable project compilation */
17+
// "removeComments": false, /* Do not emit comments to output. */
18+
// "noEmit": true, /* Do not emit outputs. */
19+
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
20+
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
21+
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
22+
23+
/* Strict Type-Checking Options */
24+
"strict": true, /* Enable all strict type-checking options. */
25+
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
26+
"strictNullChecks": true, /* Enable strict null checks. */
27+
"strictFunctionTypes": true, /* Enable strict checking of function types. */
28+
"strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
29+
"strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
30+
"noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
31+
"alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
32+
33+
/* Additional Checks */
34+
"noUnusedLocals": true, /* Report errors on unused locals. */
35+
"noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
36+
// "noUnusedParameters": true, /* Report errors on unused parameters. */
37+
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
38+
39+
/* Module Resolution Options */
40+
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
41+
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
42+
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
43+
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
44+
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
45+
// "typeRoots": [], /* List of folders to include type definitions from. */
46+
// "types": [], /* Type declaration files to be included in compilation. */
47+
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
48+
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
49+
50+
/* Source Map Options */
51+
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
52+
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
53+
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
54+
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
55+
56+
/* Experimental Options */
57+
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
58+
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
59+
},
60+
"include": [
61+
"*.ts"
62+
],
63+
"exclude": [
64+
"node_modules",
65+
"dist"
66+
]
67+
}

0 commit comments

Comments
 (0)