├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── images ├── app.png └── architecture.png ├── mobile ├── .gitignore ├── AmplifyModels │ ├── AmplifyModels.swift │ ├── SensorValue+Schema.swift │ └── SensorValue.swift ├── amplify │ ├── auth │ │ └── resource.ts │ ├── backend.ts │ ├── data │ │ └── resource.ts │ ├── functions │ │ └── send-sensor-value │ │ │ ├── handler.ts │ │ │ └── resource.ts │ ├── package.json │ └── tsconfig.json ├── mobile.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── swiftpm │ │ │ │ └── Package.resolved │ │ └── xcuserdata │ │ │ └── davidmoser.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── davidmoser.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── mobile │ ├── AmplifyModels │ │ ├── AmplifyModels.swift │ │ ├── SensorValue+Schema.swift │ │ └── SensorValue.swift │ ├── Assets.xcassets │ │ ├── AccentColor.colorset │ │ │ └── Contents.json │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── ContentView.swift │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ ├── SensorValueService.swift │ ├── Subscriptions.swift │ ├── mobile.entitlements │ └── mobileApp.swift ├── package-lock.json └── package.json └── sensor ├── .gitignore ├── LICENSE-THIRD-PARTY ├── certs └── AmazonRootCA1.pem ├── create-sensor.js ├── delete-sensor.js ├── index.js ├── package-lock.json ├── package.json ├── policy.json └── settings.json /.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *master* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | 61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 62 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AWS AppSync IoT Core Realtime Example 2 | 3 | **Update!!** the project has been updated to use [**Amplify Gen2**](https://docs.amplify.aws/swift/) to deploy the backend services in AWS. 4 | 5 | This application demonstrates an iPhone receiving real-time updates from an IoT sensor. The solution is built with AWS AppSync and AWS IoT Core technologies. 6 | 7 | ![Image description](images/app.png) 8 | 9 | ## Architecture 10 | 11 | ![Image description](images/architecture.png) 12 | 13 | 1. The sensor component is developed with the AWS IoT Device SDK for Javascript. The sensor is registered as a Thing in IoT Core and publishes a random temperature in a JSON payload to the Cloud every 2 seconds. The Thing Shadow also containes meta-data about then sensor specifying the _sensor type_ as Temperature. 14 | 15 | ```json 16 | { 17 | "value": 84, 18 | "timestamp": 1570562147790 19 | } 20 | ``` 21 | 22 | 2. A rule in IoT Core subscribes to the message topic and forwards the JSON payload to a Lambda function. 23 | 24 | 3. The NodeJS Lambda function executes a GraphQL mutatation in AppSync. The mutation saves the latest value for the sensor in DynamoDB and broadcasts the latest value in real-time to the iOS application. The Lambda function uses an IAM role and policy to obtain permissions to interact with AppSync. 25 | 26 | 4. The iOS application uses the [Amplify Swift](https://github.com/aws-amplify/amplify-swift) package, built with the [AWS SDK for Swift](https://github.com/awslabs/aws-sdk-swift), to subscribe to the AppSync Sensor Value subscription. When new temperature values are received, the gauge component on the screen is updated in real-time to reflect the new sensor value. 27 | 28 | ## Getting Started 29 | 30 | ### **Prerequisites** 31 | 32 | The following software was used in the development of this application. While it may work with alternative versions, we recommend you deploy the specified minimum version. 33 | 34 | 1. An AWS account in which you have Administrator access. 35 | 36 | 2. [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) (^2.21.1) the AWS Command Line Interface (CLI) is used to configure your connection credentials to AWS. 37 | 38 | 3. [Node.js](https://nodejs.org/en/download/current/) (^18.19.0) with NPM (^10.1.0) 39 | 40 | 4. [Xcode](https://developer.apple.com/xcode/) (16.1) Xcode is used to build and debug the mobile appliction application. You will need iOS Simulator 18.0 enabled. 41 | 42 | ### **Installation** 43 | 44 | **Clone this code repository** 45 | 46 | ``` 47 | git clone https://github.com/aws-samples/aws-appsync-iot-core-realtime-example.git 48 | ``` 49 | 50 | **Switch to the mobile folder** 51 | 52 | ``` 53 | cd aws-appsync-iot-core-realtime-example/mobile 54 | ``` 55 | 56 | **Deploy the Infrastructure with Amplify Gen2** 57 | 58 | ```bash 59 | npm install 60 | 61 | npx ampx sandbox 62 | ``` 63 | 64 | The deployment is complete when you see the following output: 65 | 66 | ```bash 67 | File written: amplify_outputs.json 68 | ``` 69 | 70 | Press **CTRL-C** to exit the deployment. 71 | 72 | Resources created in your account include: 73 | 74 | - AppSync GraphQL API 75 | - DynamoDB table 76 | - Lambda function 77 | - IoT Rule 78 | 79 | **Install the IoT Sensor Simulator** 80 | 81 | Open a new terminal window then switch to the app's **sensor** folder (aws-appsync-iot-core-realtime-example/sensor). 82 | 83 | Install the Node.js packages, and run the Node.js app to create your sensor as a **Thing** in AWS IoT Core. It will also create and install the certificates your sensor needs to authenticate to IoT Core. 84 | 85 | From the **sensor** folder: 86 | 87 | ``` 88 | npm install 89 | node create-sensor.js 90 | ``` 91 | 92 | ## Run the App 93 | 94 | ### Start the IoT Sensor 95 | 96 | From the **sensor** terminal window: 97 | 98 | ``` 99 | node index.js 100 | ``` 101 | 102 | You will see output from the app as it connects to IoT Core, transmits its shadow document, and publishes new temperature messages every 2 seconds. 103 | 104 | ``` 105 | connected to IoT Hub 106 | 107 | published to shadow topic $aws/things/aws-iot-mobile-demo-sensor/shadow/update {"state":{"reported":{"sensorType":"Temperature"}}} 108 | 109 | published to topic dt/sensor-view/aws-iot-mobile-demo-sensor/sensor-value {"value":77,"timestamp":1592073890804} 110 | 111 | published to topic dt/sensor-view/aws-iot-mobile-demo-sensor/sensor-value {"value":76,"timestamp":1592073892807} 112 | 113 | published to topic dt/sensor-view/aws-iot-mobile-demo-sensor/sensor-value {"value":77,"timestamp":1592073894810} 114 | ``` 115 | 116 | Keep this app running and switch to your mobile terminal window. 117 | 118 | ### Start the iPhone app 119 | 120 | From the terminal window pointing to the **mobile** folder (aws-appsync-iot-core-realtime-example/mobile) and open the Xcode project: 121 | 122 | ``` 123 | open mobile.xcodeproj 124 | ``` 125 | 126 | **Add Amplify Configuration File to Xcode Project** 127 | 128 | In the Xcode project select **File/Add files to mobile** from the main menu and add the **amplify_outputs.json** file generated by Amplify. Select the option to **Copy** the file and set **mobile** as the Target. 129 | 130 | Select the "Run" arrow button to start the app. 131 | 132 | **Use the App!** 133 | 134 | You should now see a screen similar to the one at the top of this guide. If you look at the terminal window running the sensor app, you shoud see the values published to the Cloud reflected in the iPhone app's sensor gauge in real-time. 135 | 136 | ## Cleanup 137 | 138 | Once you are finished working with this project, you may want to delete the resources it created in your AWS account. 139 | 140 | From the **mobile** folder: 141 | 142 | ``` 143 | npx ampx sandbox delete 144 | ``` 145 | 146 | From the **sensor** folder: 147 | 148 | ``` 149 | node delete-sensor.js 150 | ``` 151 | 152 | ## License 153 | 154 | This sample code is made available under a modified MIT-0 license. See the LICENSE file. 155 | -------------------------------------------------------------------------------- /images/app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-appsync-iot-core-realtime-example/7c8b480f64559cfea8c942ea9bf1ae1d0142915f/images/app.png -------------------------------------------------------------------------------- /images/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-appsync-iot-core-realtime-example/7c8b480f64559cfea8c942ea9bf1ae1d0142915f/images/architecture.png -------------------------------------------------------------------------------- /mobile/.gitignore: -------------------------------------------------------------------------------- 1 | # amplify 2 | node_modules 3 | .amplify 4 | amplify_outputs* 5 | amplifyconfiguration* 6 | mobile/amplify_outputs.json 7 | -------------------------------------------------------------------------------- /mobile/AmplifyModels/AmplifyModels.swift: -------------------------------------------------------------------------------- 1 | // swiftlint:disable all 2 | import Amplify 3 | import Foundation 4 | 5 | // Contains the set of classes that conforms to the `Model` protocol. 6 | 7 | final public class AmplifyModels: AmplifyModelRegistration { 8 | public let version: String = "33cd80b8343a60126657a25bc9025724" 9 | 10 | public func registerModels(registry: ModelRegistry.Type) { 11 | ModelRegistry.register(modelType: SensorValue.self) 12 | } 13 | } -------------------------------------------------------------------------------- /mobile/AmplifyModels/SensorValue+Schema.swift: -------------------------------------------------------------------------------- 1 | // swiftlint:disable all 2 | import Amplify 3 | import Foundation 4 | 5 | extension SensorValue { 6 | // MARK: - CodingKeys 7 | public enum CodingKeys: String, ModelKey { 8 | case id 9 | case sensorId 10 | case value 11 | case timestamp 12 | case createdAt 13 | case updatedAt 14 | } 15 | 16 | public static let keys = CodingKeys.self 17 | // MARK: - ModelSchema 18 | 19 | public static let schema = defineSchema { model in 20 | let sensorValue = SensorValue.keys 21 | 22 | model.authRules = [ 23 | rule(allow: .private, operations: [.create, .update, .delete, .read]) 24 | ] 25 | 26 | model.listPluralName = "SensorValues" 27 | model.syncPluralName = "SensorValues" 28 | 29 | model.attributes( 30 | .index(fields: ["id"], name: nil), 31 | .primaryKey(fields: [sensorValue.id]) 32 | ) 33 | 34 | model.fields( 35 | .field(sensorValue.id, is: .required, ofType: .string), 36 | .field(sensorValue.sensorId, is: .required, ofType: .string), 37 | .field(sensorValue.value, is: .required, ofType: .double), 38 | .field(sensorValue.timestamp, is: .required, ofType: .int), 39 | .field(sensorValue.createdAt, is: .optional, isReadOnly: true, ofType: .dateTime), 40 | .field(sensorValue.updatedAt, is: .optional, isReadOnly: true, ofType: .dateTime) 41 | ) 42 | } 43 | public class Path: ModelPath { } 44 | 45 | public static var rootPath: PropertyContainerPath? { Path() } 46 | } 47 | 48 | extension SensorValue: ModelIdentifiable { 49 | public typealias IdentifierFormat = ModelIdentifierFormat.Default 50 | public typealias IdentifierProtocol = DefaultModelIdentifier 51 | } 52 | extension ModelPath where ModelType == SensorValue { 53 | public var id: FieldPath { 54 | string("id") 55 | } 56 | public var sensorId: FieldPath { 57 | string("sensorId") 58 | } 59 | public var value: FieldPath { 60 | double("value") 61 | } 62 | public var timestamp: FieldPath { 63 | int("timestamp") 64 | } 65 | public var createdAt: FieldPath { 66 | datetime("createdAt") 67 | } 68 | public var updatedAt: FieldPath { 69 | datetime("updatedAt") 70 | } 71 | } -------------------------------------------------------------------------------- /mobile/AmplifyModels/SensorValue.swift: -------------------------------------------------------------------------------- 1 | // swiftlint:disable all 2 | import Amplify 3 | import Foundation 4 | 5 | public struct SensorValue: Model { 6 | public let id: String 7 | public var sensorId: String 8 | public var value: Double 9 | public var timestamp: Int 10 | public var createdAt: Temporal.DateTime? 11 | public var updatedAt: Temporal.DateTime? 12 | 13 | public init(id: String = UUID().uuidString, 14 | sensorId: String, 15 | value: Double, 16 | timestamp: Int) { 17 | self.init(id: id, 18 | sensorId: sensorId, 19 | value: value, 20 | timestamp: timestamp, 21 | createdAt: nil, 22 | updatedAt: nil) 23 | } 24 | internal init(id: String = UUID().uuidString, 25 | sensorId: String, 26 | value: Double, 27 | timestamp: Int, 28 | createdAt: Temporal.DateTime? = nil, 29 | updatedAt: Temporal.DateTime? = nil) { 30 | self.id = id 31 | self.sensorId = sensorId 32 | self.value = value 33 | self.timestamp = timestamp 34 | self.createdAt = createdAt 35 | self.updatedAt = updatedAt 36 | } 37 | } -------------------------------------------------------------------------------- /mobile/amplify/auth/resource.ts: -------------------------------------------------------------------------------- 1 | import { defineAuth } from '@aws-amplify/backend'; 2 | 3 | /** 4 | * Define and configure your auth resource 5 | * @see https://docs.amplify.aws/gen2/build-a-backend/auth 6 | */ 7 | export const auth = defineAuth({ 8 | loginWith: { 9 | email: true, 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /mobile/amplify/backend.ts: -------------------------------------------------------------------------------- 1 | import { defineBackend } from "@aws-amplify/backend"; 2 | import { ServicePrincipal } from "aws-cdk-lib/aws-iam"; 3 | import { CfnTopicRule } from "aws-cdk-lib/aws-iot"; 4 | import { auth } from "./auth/resource"; 5 | import { data } from "./data/resource"; 6 | import { sendSensorValue } from "./functions/send-sensor-value/resource"; 7 | 8 | const backend = defineBackend({ 9 | auth, 10 | data, 11 | sendSensorValue, 12 | }); 13 | 14 | // disable unauthenticated access 15 | const { cfnIdentityPool } = backend.auth.resources.cfnResources; 16 | cfnIdentityPool.allowUnauthenticatedIdentities = false; 17 | 18 | // IoT Resources 19 | const iotStack = backend.createStack("iot-stack"); 20 | 21 | const sendSensorValueLambda = backend.sendSensorValue.resources.lambda; 22 | 23 | // create a rule to process messages from the sensors - send them to the lambda function 24 | const rule = new CfnTopicRule(iotStack, "SendSensorValueRule", { 25 | topicRulePayload: { 26 | sql: "select * as data, topic(3) as sensorId from 'dt/sensor-view/+/sensor-value'", 27 | actions: [ 28 | { 29 | lambda: { 30 | functionArn: sendSensorValueLambda.functionArn, 31 | }, 32 | }, 33 | ], 34 | }, 35 | }); 36 | 37 | // allow IoT rule to invoke the lambda function 38 | sendSensorValueLambda.addPermission("AllowIoTInvoke", { 39 | principal: new ServicePrincipal("iot.amazonaws.com"), 40 | sourceArn: `arn:aws:iot:${iotStack.region}:${iotStack.account}:rule/SendSensorValueRule*`, 41 | }); 42 | -------------------------------------------------------------------------------- /mobile/amplify/data/resource.ts: -------------------------------------------------------------------------------- 1 | import { type ClientSchema, a, defineData } from "@aws-amplify/backend"; 2 | import { sendSensorValue } from "../functions/send-sensor-value/resource"; 3 | 4 | const schema = a 5 | .schema({ 6 | SensorValue: a.model({ 7 | id: a.id(), 8 | sensorId: a.string().required(), 9 | value: a.float().required(), 10 | timestamp: a.timestamp().required(), 11 | }), 12 | }) 13 | .authorization((allow) => [ 14 | allow.authenticated(), 15 | allow.resource(sendSensorValue), 16 | ]); 17 | 18 | export type Schema = ClientSchema; 19 | 20 | export const data = defineData({ 21 | schema, 22 | authorizationModes: { 23 | defaultAuthorizationMode: "userPool", 24 | }, 25 | }); 26 | -------------------------------------------------------------------------------- /mobile/amplify/functions/send-sensor-value/handler.ts: -------------------------------------------------------------------------------- 1 | import type { Handler } from "aws-lambda"; 2 | import crypto from "@aws-crypto/sha256-js"; 3 | import { defaultProvider } from "@aws-sdk/credential-provider-node"; 4 | import { SignatureV4 } from "@aws-sdk/signature-v4"; 5 | import { HttpRequest } from "@aws-sdk/protocol-http"; 6 | import { default as fetch, Request } from "node-fetch"; 7 | 8 | const GRAPHQL_ENDPOINT = process.env.AMPLIFY_DATA_GRAPHQL_ENDPOINT || ""; 9 | const AWS_REGION = process.env.AWS_REGION || ""; 10 | const { Sha256 } = crypto; 11 | 12 | export const handler: Handler = async (event) => { 13 | console.log("event", event); 14 | 15 | const query = /* GraphQL */ ` 16 | mutation CreateSensorValue($input: CreateSensorValueInput!) { 17 | createSensorValue(input: $input) { 18 | id 19 | sensorId 20 | value 21 | timestamp 22 | createdAt 23 | updatedAt 24 | } 25 | } 26 | `; 27 | 28 | const variables = { 29 | input: { 30 | sensorId: event.sensorId, 31 | value: event.data.value, 32 | timestamp: event.data.timestamp, 33 | }, 34 | }; 35 | 36 | const endpoint = new URL(GRAPHQL_ENDPOINT); 37 | 38 | const signer = new SignatureV4({ 39 | credentials: defaultProvider(), 40 | region: AWS_REGION, 41 | service: "appsync", 42 | sha256: Sha256, 43 | }); 44 | 45 | const requestToBeSigned = new HttpRequest({ 46 | method: "POST", 47 | headers: { 48 | "Content-Type": "application/json", 49 | host: endpoint.host, 50 | }, 51 | hostname: endpoint.host, 52 | body: JSON.stringify({ query, variables }), 53 | path: endpoint.pathname, 54 | }); 55 | 56 | const signed = await signer.sign(requestToBeSigned); 57 | const request = new Request(endpoint, signed); 58 | 59 | let statusCode = 200; 60 | let body; 61 | let response; 62 | 63 | try { 64 | response = await fetch(request); 65 | body = await response.json(); 66 | console.log(body); 67 | } catch (error: any) { 68 | console.log(error); 69 | statusCode = 500; 70 | body = { 71 | errors: [ 72 | { 73 | message: error.message, 74 | }, 75 | ], 76 | }; 77 | } 78 | 79 | return { 80 | statusCode, 81 | body: JSON.stringify(body), 82 | }; 83 | }; 84 | -------------------------------------------------------------------------------- /mobile/amplify/functions/send-sensor-value/resource.ts: -------------------------------------------------------------------------------- 1 | import { defineFunction } from "@aws-amplify/backend"; 2 | 3 | export const sendSensorValue = defineFunction({ 4 | entry: "./handler.ts", 5 | name: "sendSensorValue", 6 | resourceGroupName: "data", 7 | }); 8 | -------------------------------------------------------------------------------- /mobile/amplify/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module" 3 | } -------------------------------------------------------------------------------- /mobile/amplify/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2022", 4 | "module": "es2022", 5 | "moduleResolution": "bundler", 6 | "resolveJsonModule": true, 7 | "esModuleInterop": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "strict": true, 10 | "skipLibCheck": true, 11 | "paths": { 12 | "$amplify/*": [ 13 | "../.amplify/generated/*" 14 | ] 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /mobile/mobile.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 77; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4EAD15B92D0F7DC3003C16AB /* AWSAPIPlugin in Frameworks */ = {isa = PBXBuildFile; productRef = 4EAD15B82D0F7DC3003C16AB /* AWSAPIPlugin */; }; 11 | 4EAD15BB2D0F7DC3003C16AB /* AWSCognitoAuthPlugin in Frameworks */ = {isa = PBXBuildFile; productRef = 4EAD15BA2D0F7DC3003C16AB /* AWSCognitoAuthPlugin */; }; 12 | 4EAD15BD2D0F7DC3003C16AB /* Amplify in Frameworks */ = {isa = PBXBuildFile; productRef = 4EAD15BC2D0F7DC3003C16AB /* Amplify */; }; 13 | 4EAD15C02D0F7DF9003C16AB /* Authenticator in Frameworks */ = {isa = PBXBuildFile; productRef = 4EAD15BF2D0F7DF9003C16AB /* Authenticator */; }; 14 | /* End PBXBuildFile section */ 15 | 16 | /* Begin PBXFileReference section */ 17 | 4EAD15A32D0F79D6003C16AB /* mobile.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = mobile.app; sourceTree = BUILT_PRODUCTS_DIR; }; 18 | /* End PBXFileReference section */ 19 | 20 | /* Begin PBXFileSystemSynchronizedRootGroup section */ 21 | 4EAD15A52D0F79D6003C16AB /* mobile */ = { 22 | isa = PBXFileSystemSynchronizedRootGroup; 23 | path = mobile; 24 | sourceTree = ""; 25 | }; 26 | /* End PBXFileSystemSynchronizedRootGroup section */ 27 | 28 | /* Begin PBXFrameworksBuildPhase section */ 29 | 4EAD15A02D0F79D6003C16AB /* Frameworks */ = { 30 | isa = PBXFrameworksBuildPhase; 31 | buildActionMask = 2147483647; 32 | files = ( 33 | 4EAD15C02D0F7DF9003C16AB /* Authenticator in Frameworks */, 34 | 4EAD15BD2D0F7DC3003C16AB /* Amplify in Frameworks */, 35 | 4EAD15B92D0F7DC3003C16AB /* AWSAPIPlugin in Frameworks */, 36 | 4EAD15BB2D0F7DC3003C16AB /* AWSCognitoAuthPlugin in Frameworks */, 37 | ); 38 | runOnlyForDeploymentPostprocessing = 0; 39 | }; 40 | /* End PBXFrameworksBuildPhase section */ 41 | 42 | /* Begin PBXGroup section */ 43 | 4EAD159A2D0F79D6003C16AB = { 44 | isa = PBXGroup; 45 | children = ( 46 | 4EAD15A52D0F79D6003C16AB /* mobile */, 47 | 4EAD15A42D0F79D6003C16AB /* Products */, 48 | ); 49 | sourceTree = ""; 50 | }; 51 | 4EAD15A42D0F79D6003C16AB /* Products */ = { 52 | isa = PBXGroup; 53 | children = ( 54 | 4EAD15A32D0F79D6003C16AB /* mobile.app */, 55 | ); 56 | name = Products; 57 | sourceTree = ""; 58 | }; 59 | /* End PBXGroup section */ 60 | 61 | /* Begin PBXNativeTarget section */ 62 | 4EAD15A22D0F79D6003C16AB /* mobile */ = { 63 | isa = PBXNativeTarget; 64 | buildConfigurationList = 4EAD15B22D0F79D7003C16AB /* Build configuration list for PBXNativeTarget "mobile" */; 65 | buildPhases = ( 66 | 4EAD159F2D0F79D6003C16AB /* Sources */, 67 | 4EAD15A02D0F79D6003C16AB /* Frameworks */, 68 | 4EAD15A12D0F79D6003C16AB /* Resources */, 69 | ); 70 | buildRules = ( 71 | ); 72 | dependencies = ( 73 | ); 74 | fileSystemSynchronizedGroups = ( 75 | 4EAD15A52D0F79D6003C16AB /* mobile */, 76 | ); 77 | name = mobile; 78 | packageProductDependencies = ( 79 | 4EAD15B82D0F7DC3003C16AB /* AWSAPIPlugin */, 80 | 4EAD15BA2D0F7DC3003C16AB /* AWSCognitoAuthPlugin */, 81 | 4EAD15BC2D0F7DC3003C16AB /* Amplify */, 82 | 4EAD15BF2D0F7DF9003C16AB /* Authenticator */, 83 | ); 84 | productName = mobile; 85 | productReference = 4EAD15A32D0F79D6003C16AB /* mobile.app */; 86 | productType = "com.apple.product-type.application"; 87 | }; 88 | /* End PBXNativeTarget section */ 89 | 90 | /* Begin PBXProject section */ 91 | 4EAD159B2D0F79D6003C16AB /* Project object */ = { 92 | isa = PBXProject; 93 | attributes = { 94 | BuildIndependentTargetsInParallel = 1; 95 | LastSwiftUpdateCheck = 1610; 96 | LastUpgradeCheck = 1610; 97 | TargetAttributes = { 98 | 4EAD15A22D0F79D6003C16AB = { 99 | CreatedOnToolsVersion = 16.1; 100 | }; 101 | }; 102 | }; 103 | buildConfigurationList = 4EAD159E2D0F79D6003C16AB /* Build configuration list for PBXProject "mobile" */; 104 | developmentRegion = en; 105 | hasScannedForEncodings = 0; 106 | knownRegions = ( 107 | en, 108 | Base, 109 | ); 110 | mainGroup = 4EAD159A2D0F79D6003C16AB; 111 | minimizedProjectReferenceProxies = 1; 112 | packageReferences = ( 113 | 4EAD15B72D0F7DC3003C16AB /* XCRemoteSwiftPackageReference "amplify-swift" */, 114 | 4EAD15BE2D0F7DF9003C16AB /* XCRemoteSwiftPackageReference "amplify-ui-swift-authenticator" */, 115 | ); 116 | preferredProjectObjectVersion = 77; 117 | productRefGroup = 4EAD15A42D0F79D6003C16AB /* Products */; 118 | projectDirPath = ""; 119 | projectRoot = ""; 120 | targets = ( 121 | 4EAD15A22D0F79D6003C16AB /* mobile */, 122 | ); 123 | }; 124 | /* End PBXProject section */ 125 | 126 | /* Begin PBXResourcesBuildPhase section */ 127 | 4EAD15A12D0F79D6003C16AB /* Resources */ = { 128 | isa = PBXResourcesBuildPhase; 129 | buildActionMask = 2147483647; 130 | files = ( 131 | ); 132 | runOnlyForDeploymentPostprocessing = 0; 133 | }; 134 | /* End PBXResourcesBuildPhase section */ 135 | 136 | /* Begin PBXSourcesBuildPhase section */ 137 | 4EAD159F2D0F79D6003C16AB /* Sources */ = { 138 | isa = PBXSourcesBuildPhase; 139 | buildActionMask = 2147483647; 140 | files = ( 141 | ); 142 | runOnlyForDeploymentPostprocessing = 0; 143 | }; 144 | /* End PBXSourcesBuildPhase section */ 145 | 146 | /* Begin XCBuildConfiguration section */ 147 | 4EAD15B02D0F79D7003C16AB /* Debug */ = { 148 | isa = XCBuildConfiguration; 149 | buildSettings = { 150 | ALWAYS_SEARCH_USER_PATHS = NO; 151 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 152 | CLANG_ANALYZER_NONNULL = YES; 153 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 154 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 155 | CLANG_ENABLE_MODULES = YES; 156 | CLANG_ENABLE_OBJC_ARC = YES; 157 | CLANG_ENABLE_OBJC_WEAK = YES; 158 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 159 | CLANG_WARN_BOOL_CONVERSION = YES; 160 | CLANG_WARN_COMMA = YES; 161 | CLANG_WARN_CONSTANT_CONVERSION = YES; 162 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 163 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 164 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 165 | CLANG_WARN_EMPTY_BODY = YES; 166 | CLANG_WARN_ENUM_CONVERSION = YES; 167 | CLANG_WARN_INFINITE_RECURSION = YES; 168 | CLANG_WARN_INT_CONVERSION = YES; 169 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 170 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 171 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 172 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 173 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 174 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 175 | CLANG_WARN_STRICT_PROTOTYPES = YES; 176 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 177 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 178 | CLANG_WARN_UNREACHABLE_CODE = YES; 179 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 180 | COPY_PHASE_STRIP = NO; 181 | DEBUG_INFORMATION_FORMAT = dwarf; 182 | ENABLE_STRICT_OBJC_MSGSEND = YES; 183 | ENABLE_TESTABILITY = YES; 184 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 185 | GCC_C_LANGUAGE_STANDARD = gnu17; 186 | GCC_DYNAMIC_NO_PIC = NO; 187 | GCC_NO_COMMON_BLOCKS = YES; 188 | GCC_OPTIMIZATION_LEVEL = 0; 189 | GCC_PREPROCESSOR_DEFINITIONS = ( 190 | "DEBUG=1", 191 | "$(inherited)", 192 | ); 193 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 194 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 195 | GCC_WARN_UNDECLARED_SELECTOR = YES; 196 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 197 | GCC_WARN_UNUSED_FUNCTION = YES; 198 | GCC_WARN_UNUSED_VARIABLE = YES; 199 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 200 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 201 | MTL_FAST_MATH = YES; 202 | ONLY_ACTIVE_ARCH = YES; 203 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; 204 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 205 | }; 206 | name = Debug; 207 | }; 208 | 4EAD15B12D0F79D7003C16AB /* Release */ = { 209 | isa = XCBuildConfiguration; 210 | buildSettings = { 211 | ALWAYS_SEARCH_USER_PATHS = NO; 212 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; 213 | CLANG_ANALYZER_NONNULL = YES; 214 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 215 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 216 | CLANG_ENABLE_MODULES = YES; 217 | CLANG_ENABLE_OBJC_ARC = YES; 218 | CLANG_ENABLE_OBJC_WEAK = YES; 219 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 220 | CLANG_WARN_BOOL_CONVERSION = YES; 221 | CLANG_WARN_COMMA = YES; 222 | CLANG_WARN_CONSTANT_CONVERSION = YES; 223 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 224 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 225 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 226 | CLANG_WARN_EMPTY_BODY = YES; 227 | CLANG_WARN_ENUM_CONVERSION = YES; 228 | CLANG_WARN_INFINITE_RECURSION = YES; 229 | CLANG_WARN_INT_CONVERSION = YES; 230 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 231 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 232 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 233 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 234 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 235 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 236 | CLANG_WARN_STRICT_PROTOTYPES = YES; 237 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 238 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 239 | CLANG_WARN_UNREACHABLE_CODE = YES; 240 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 241 | COPY_PHASE_STRIP = NO; 242 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 243 | ENABLE_NS_ASSERTIONS = NO; 244 | ENABLE_STRICT_OBJC_MSGSEND = YES; 245 | ENABLE_USER_SCRIPT_SANDBOXING = YES; 246 | GCC_C_LANGUAGE_STANDARD = gnu17; 247 | GCC_NO_COMMON_BLOCKS = YES; 248 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 249 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 250 | GCC_WARN_UNDECLARED_SELECTOR = YES; 251 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 252 | GCC_WARN_UNUSED_FUNCTION = YES; 253 | GCC_WARN_UNUSED_VARIABLE = YES; 254 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES; 255 | MTL_ENABLE_DEBUG_INFO = NO; 256 | MTL_FAST_MATH = YES; 257 | SWIFT_COMPILATION_MODE = wholemodule; 258 | }; 259 | name = Release; 260 | }; 261 | 4EAD15B32D0F79D7003C16AB /* Debug */ = { 262 | isa = XCBuildConfiguration; 263 | buildSettings = { 264 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 265 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 266 | CODE_SIGN_ENTITLEMENTS = mobile/mobile.entitlements; 267 | CODE_SIGN_STYLE = Automatic; 268 | CURRENT_PROJECT_VERSION = 1; 269 | DEVELOPMENT_ASSET_PATHS = "\"mobile/Preview Content\""; 270 | ENABLE_PREVIEWS = YES; 271 | GENERATE_INFOPLIST_FILE = YES; 272 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; 273 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; 274 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; 275 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; 276 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; 277 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; 278 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault; 279 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; 280 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 281 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 282 | IPHONEOS_DEPLOYMENT_TARGET = 18.1; 283 | LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; 284 | "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; 285 | MACOSX_DEPLOYMENT_TARGET = 15.1; 286 | MARKETING_VERSION = 1.0; 287 | PRODUCT_BUNDLE_IDENTIFIER = com.aws.samples.iotmobile.mobile; 288 | PRODUCT_NAME = "$(TARGET_NAME)"; 289 | SDKROOT = auto; 290 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; 291 | SWIFT_EMIT_LOC_STRINGS = YES; 292 | SWIFT_VERSION = 5.0; 293 | TARGETED_DEVICE_FAMILY = "1,2,7"; 294 | XROS_DEPLOYMENT_TARGET = 2.1; 295 | }; 296 | name = Debug; 297 | }; 298 | 4EAD15B42D0F79D7003C16AB /* Release */ = { 299 | isa = XCBuildConfiguration; 300 | buildSettings = { 301 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 302 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 303 | CODE_SIGN_ENTITLEMENTS = mobile/mobile.entitlements; 304 | CODE_SIGN_STYLE = Automatic; 305 | CURRENT_PROJECT_VERSION = 1; 306 | DEVELOPMENT_ASSET_PATHS = "\"mobile/Preview Content\""; 307 | ENABLE_PREVIEWS = YES; 308 | GENERATE_INFOPLIST_FILE = YES; 309 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; 310 | "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; 311 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; 312 | "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; 313 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; 314 | "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; 315 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault; 316 | "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; 317 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 318 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 319 | IPHONEOS_DEPLOYMENT_TARGET = 18.1; 320 | LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; 321 | "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; 322 | MACOSX_DEPLOYMENT_TARGET = 15.1; 323 | MARKETING_VERSION = 1.0; 324 | PRODUCT_BUNDLE_IDENTIFIER = com.aws.samples.iotmobile.mobile; 325 | PRODUCT_NAME = "$(TARGET_NAME)"; 326 | SDKROOT = auto; 327 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos"; 328 | SWIFT_EMIT_LOC_STRINGS = YES; 329 | SWIFT_VERSION = 5.0; 330 | TARGETED_DEVICE_FAMILY = "1,2,7"; 331 | XROS_DEPLOYMENT_TARGET = 2.1; 332 | }; 333 | name = Release; 334 | }; 335 | /* End XCBuildConfiguration section */ 336 | 337 | /* Begin XCConfigurationList section */ 338 | 4EAD159E2D0F79D6003C16AB /* Build configuration list for PBXProject "mobile" */ = { 339 | isa = XCConfigurationList; 340 | buildConfigurations = ( 341 | 4EAD15B02D0F79D7003C16AB /* Debug */, 342 | 4EAD15B12D0F79D7003C16AB /* Release */, 343 | ); 344 | defaultConfigurationIsVisible = 0; 345 | defaultConfigurationName = Release; 346 | }; 347 | 4EAD15B22D0F79D7003C16AB /* Build configuration list for PBXNativeTarget "mobile" */ = { 348 | isa = XCConfigurationList; 349 | buildConfigurations = ( 350 | 4EAD15B32D0F79D7003C16AB /* Debug */, 351 | 4EAD15B42D0F79D7003C16AB /* Release */, 352 | ); 353 | defaultConfigurationIsVisible = 0; 354 | defaultConfigurationName = Release; 355 | }; 356 | /* End XCConfigurationList section */ 357 | 358 | /* Begin XCRemoteSwiftPackageReference section */ 359 | 4EAD15B72D0F7DC3003C16AB /* XCRemoteSwiftPackageReference "amplify-swift" */ = { 360 | isa = XCRemoteSwiftPackageReference; 361 | repositoryURL = "https://github.com/aws-amplify/amplify-swift"; 362 | requirement = { 363 | kind = upToNextMajorVersion; 364 | minimumVersion = 2.45.2; 365 | }; 366 | }; 367 | 4EAD15BE2D0F7DF9003C16AB /* XCRemoteSwiftPackageReference "amplify-ui-swift-authenticator" */ = { 368 | isa = XCRemoteSwiftPackageReference; 369 | repositoryURL = "https://github.com/aws-amplify/amplify-ui-swift-authenticator"; 370 | requirement = { 371 | kind = upToNextMajorVersion; 372 | minimumVersion = 1.2.2; 373 | }; 374 | }; 375 | /* End XCRemoteSwiftPackageReference section */ 376 | 377 | /* Begin XCSwiftPackageProductDependency section */ 378 | 4EAD15B82D0F7DC3003C16AB /* AWSAPIPlugin */ = { 379 | isa = XCSwiftPackageProductDependency; 380 | package = 4EAD15B72D0F7DC3003C16AB /* XCRemoteSwiftPackageReference "amplify-swift" */; 381 | productName = AWSAPIPlugin; 382 | }; 383 | 4EAD15BA2D0F7DC3003C16AB /* AWSCognitoAuthPlugin */ = { 384 | isa = XCSwiftPackageProductDependency; 385 | package = 4EAD15B72D0F7DC3003C16AB /* XCRemoteSwiftPackageReference "amplify-swift" */; 386 | productName = AWSCognitoAuthPlugin; 387 | }; 388 | 4EAD15BC2D0F7DC3003C16AB /* Amplify */ = { 389 | isa = XCSwiftPackageProductDependency; 390 | package = 4EAD15B72D0F7DC3003C16AB /* XCRemoteSwiftPackageReference "amplify-swift" */; 391 | productName = Amplify; 392 | }; 393 | 4EAD15BF2D0F7DF9003C16AB /* Authenticator */ = { 394 | isa = XCSwiftPackageProductDependency; 395 | package = 4EAD15BE2D0F7DF9003C16AB /* XCRemoteSwiftPackageReference "amplify-ui-swift-authenticator" */; 396 | productName = Authenticator; 397 | }; 398 | /* End XCSwiftPackageProductDependency section */ 399 | }; 400 | rootObject = 4EAD159B2D0F79D6003C16AB /* Project object */; 401 | } 402 | -------------------------------------------------------------------------------- /mobile/mobile.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /mobile/mobile.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "originHash" : "d6d9d72c9e76f534839feaa3af5ed7b7c30d6f344b038239032fd5e91ece2b56", 3 | "pins" : [ 4 | { 5 | "identity" : "amplify-swift", 6 | "kind" : "remoteSourceControl", 7 | "location" : "https://github.com/aws-amplify/amplify-swift", 8 | "state" : { 9 | "revision" : "0a78846e5162a31040e54058bb58af54a60e7938", 10 | "version" : "2.45.2" 11 | } 12 | }, 13 | { 14 | "identity" : "amplify-swift-utils-notifications", 15 | "kind" : "remoteSourceControl", 16 | "location" : "https://github.com/aws-amplify/amplify-swift-utils-notifications.git", 17 | "state" : { 18 | "revision" : "959eec669ba97c7d923b963c3e66ca8a0b2737f6", 19 | "version" : "1.1.1" 20 | } 21 | }, 22 | { 23 | "identity" : "amplify-ui-swift-authenticator", 24 | "kind" : "remoteSourceControl", 25 | "location" : "https://github.com/aws-amplify/amplify-ui-swift-authenticator", 26 | "state" : { 27 | "revision" : "a94155b476234fdd62765a596d582ad30fe04a40", 28 | "version" : "1.2.2" 29 | } 30 | }, 31 | { 32 | "identity" : "aws-crt-swift", 33 | "kind" : "remoteSourceControl", 34 | "location" : "https://github.com/awslabs/aws-crt-swift", 35 | "state" : { 36 | "revision" : "3f844bef042cc0a4c3381f7090414ce3f9a7e935", 37 | "version" : "0.37.0" 38 | } 39 | }, 40 | { 41 | "identity" : "aws-sdk-swift", 42 | "kind" : "remoteSourceControl", 43 | "location" : "https://github.com/awslabs/aws-sdk-swift", 44 | "state" : { 45 | "revision" : "c6c1064da9bfccb119a7a8ab9ba636fb3bbfa6f5", 46 | "version" : "1.0.47" 47 | } 48 | }, 49 | { 50 | "identity" : "smithy-swift", 51 | "kind" : "remoteSourceControl", 52 | "location" : "https://github.com/smithy-lang/smithy-swift", 53 | "state" : { 54 | "revision" : "3cd9f181b3ba8ff71da43bf53c09f8de6790a4ad", 55 | "version" : "0.96.0" 56 | } 57 | }, 58 | { 59 | "identity" : "sqlite.swift", 60 | "kind" : "remoteSourceControl", 61 | "location" : "https://github.com/stephencelis/SQLite.swift.git", 62 | "state" : { 63 | "revision" : "a95fc6df17d108bd99210db5e8a9bac90fe984b8", 64 | "version" : "0.15.3" 65 | } 66 | }, 67 | { 68 | "identity" : "swift-log", 69 | "kind" : "remoteSourceControl", 70 | "location" : "https://github.com/apple/swift-log.git", 71 | "state" : { 72 | "revision" : "96a2f8a0fa41e9e09af4585e2724c4e825410b91", 73 | "version" : "1.6.2" 74 | } 75 | } 76 | ], 77 | "version" : 3 78 | } 79 | -------------------------------------------------------------------------------- /mobile/mobile.xcodeproj/project.xcworkspace/xcuserdata/davidmoser.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/aws-appsync-iot-core-realtime-example/7c8b480f64559cfea8c942ea9bf1ae1d0142915f/mobile/mobile.xcodeproj/project.xcworkspace/xcuserdata/davidmoser.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /mobile/mobile.xcodeproj/xcuserdata/davidmoser.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | mobile.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /mobile/mobile/AmplifyModels/AmplifyModels.swift: -------------------------------------------------------------------------------- 1 | // swiftlint:disable all 2 | import Amplify 3 | import Foundation 4 | 5 | // Contains the set of classes that conforms to the `Model` protocol. 6 | 7 | final public class AmplifyModels: AmplifyModelRegistration { 8 | public let version: String = "33cd80b8343a60126657a25bc9025724" 9 | 10 | public func registerModels(registry: ModelRegistry.Type) { 11 | ModelRegistry.register(modelType: SensorValue.self) 12 | } 13 | } -------------------------------------------------------------------------------- /mobile/mobile/AmplifyModels/SensorValue+Schema.swift: -------------------------------------------------------------------------------- 1 | // swiftlint:disable all 2 | import Amplify 3 | import Foundation 4 | 5 | extension SensorValue { 6 | // MARK: - CodingKeys 7 | public enum CodingKeys: String, ModelKey { 8 | case id 9 | case sensorId 10 | case value 11 | case timestamp 12 | case createdAt 13 | case updatedAt 14 | } 15 | 16 | public static let keys = CodingKeys.self 17 | // MARK: - ModelSchema 18 | 19 | public static let schema = defineSchema { model in 20 | let sensorValue = SensorValue.keys 21 | 22 | model.authRules = [ 23 | rule(allow: .private, operations: [.create, .update, .delete, .read]) 24 | ] 25 | 26 | model.listPluralName = "SensorValues" 27 | model.syncPluralName = "SensorValues" 28 | 29 | model.attributes( 30 | .index(fields: ["id"], name: nil), 31 | .primaryKey(fields: [sensorValue.id]) 32 | ) 33 | 34 | model.fields( 35 | .field(sensorValue.id, is: .required, ofType: .string), 36 | .field(sensorValue.sensorId, is: .required, ofType: .string), 37 | .field(sensorValue.value, is: .required, ofType: .double), 38 | .field(sensorValue.timestamp, is: .required, ofType: .int), 39 | .field(sensorValue.createdAt, is: .optional, isReadOnly: true, ofType: .dateTime), 40 | .field(sensorValue.updatedAt, is: .optional, isReadOnly: true, ofType: .dateTime) 41 | ) 42 | } 43 | public class Path: ModelPath { } 44 | 45 | public static var rootPath: PropertyContainerPath? { Path() } 46 | } 47 | 48 | extension SensorValue: ModelIdentifiable { 49 | public typealias IdentifierFormat = ModelIdentifierFormat.Default 50 | public typealias IdentifierProtocol = DefaultModelIdentifier 51 | } 52 | extension ModelPath where ModelType == SensorValue { 53 | public var id: FieldPath { 54 | string("id") 55 | } 56 | public var sensorId: FieldPath { 57 | string("sensorId") 58 | } 59 | public var value: FieldPath { 60 | double("value") 61 | } 62 | public var timestamp: FieldPath { 63 | int("timestamp") 64 | } 65 | public var createdAt: FieldPath { 66 | datetime("createdAt") 67 | } 68 | public var updatedAt: FieldPath { 69 | datetime("updatedAt") 70 | } 71 | } -------------------------------------------------------------------------------- /mobile/mobile/AmplifyModels/SensorValue.swift: -------------------------------------------------------------------------------- 1 | // swiftlint:disable all 2 | import Amplify 3 | import Foundation 4 | 5 | public struct SensorValue: Model { 6 | public let id: String 7 | public var sensorId: String 8 | public var value: Double 9 | public var timestamp: Int 10 | public var createdAt: Temporal.DateTime? 11 | public var updatedAt: Temporal.DateTime? 12 | 13 | public init(id: String = UUID().uuidString, 14 | sensorId: String, 15 | value: Double, 16 | timestamp: Int) { 17 | self.init(id: id, 18 | sensorId: sensorId, 19 | value: value, 20 | timestamp: timestamp, 21 | createdAt: nil, 22 | updatedAt: nil) 23 | } 24 | internal init(id: String = UUID().uuidString, 25 | sensorId: String, 26 | value: Double, 27 | timestamp: Int, 28 | createdAt: Temporal.DateTime? = nil, 29 | updatedAt: Temporal.DateTime? = nil) { 30 | self.id = id 31 | self.sensorId = sensorId 32 | self.value = value 33 | self.timestamp = timestamp 34 | self.createdAt = createdAt 35 | self.updatedAt = updatedAt 36 | } 37 | } -------------------------------------------------------------------------------- /mobile/mobile/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /mobile/mobile/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "platform" : "ios", 6 | "size" : "1024x1024" 7 | }, 8 | { 9 | "appearances" : [ 10 | { 11 | "appearance" : "luminosity", 12 | "value" : "dark" 13 | } 14 | ], 15 | "idiom" : "universal", 16 | "platform" : "ios", 17 | "size" : "1024x1024" 18 | }, 19 | { 20 | "appearances" : [ 21 | { 22 | "appearance" : "luminosity", 23 | "value" : "tinted" 24 | } 25 | ], 26 | "idiom" : "universal", 27 | "platform" : "ios", 28 | "size" : "1024x1024" 29 | }, 30 | { 31 | "idiom" : "mac", 32 | "scale" : "1x", 33 | "size" : "16x16" 34 | }, 35 | { 36 | "idiom" : "mac", 37 | "scale" : "2x", 38 | "size" : "16x16" 39 | }, 40 | { 41 | "idiom" : "mac", 42 | "scale" : "1x", 43 | "size" : "32x32" 44 | }, 45 | { 46 | "idiom" : "mac", 47 | "scale" : "2x", 48 | "size" : "32x32" 49 | }, 50 | { 51 | "idiom" : "mac", 52 | "scale" : "1x", 53 | "size" : "128x128" 54 | }, 55 | { 56 | "idiom" : "mac", 57 | "scale" : "2x", 58 | "size" : "128x128" 59 | }, 60 | { 61 | "idiom" : "mac", 62 | "scale" : "1x", 63 | "size" : "256x256" 64 | }, 65 | { 66 | "idiom" : "mac", 67 | "scale" : "2x", 68 | "size" : "256x256" 69 | }, 70 | { 71 | "idiom" : "mac", 72 | "scale" : "1x", 73 | "size" : "512x512" 74 | }, 75 | { 76 | "idiom" : "mac", 77 | "scale" : "2x", 78 | "size" : "512x512" 79 | } 80 | ], 81 | "info" : { 82 | "author" : "xcode", 83 | "version" : 1 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /mobile/mobile/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /mobile/mobile/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // mobile 4 | // 5 | // Created by David Moser on 12/15/24. 6 | // 7 | 8 | import SwiftUI 9 | import Amplify 10 | 11 | struct ContentView: View { 12 | 13 | // start service to receive new values from the cloud 14 | @ObservedObject var sensorValueService = SensorValueService() 15 | 16 | let gradient = Gradient(colors: [.blue, .green, .orange, .red]) 17 | 18 | var body: some View { 19 | 20 | VStack (spacing: 150) { 21 | Text("Temperature") 22 | .font(.largeTitle) 23 | 24 | Gauge(value: sensorValueService.sensorValue, in: 0...100) { 25 | } currentValueLabel: { 26 | Text(sensorValueService.sensorValue, format: .number) 27 | .foregroundColor(.gray) 28 | } minimumValueLabel: { 29 | Text("0") 30 | .foregroundColor(.blue) 31 | } maximumValueLabel: { 32 | Text("100") 33 | .foregroundColor(.red) 34 | } 35 | .gaugeStyle(.accessoryCircular) 36 | .scaleEffect(3) 37 | .tint(gradient) 38 | 39 | Text(sensorValueService.sensorTime, style: .time) 40 | .font(.title2) 41 | } 42 | .onDisappear { 43 | sensorValueService.cancelSubscription() 44 | } 45 | } 46 | } 47 | 48 | //#Preview { 49 | // ContentView() 50 | //} 51 | -------------------------------------------------------------------------------- /mobile/mobile/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /mobile/mobile/SensorValueService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SubscriptionService.swift 3 | // mobile 4 | // 5 | // Created by David Moser on 12/15/24. 6 | // 7 | 8 | import Foundation 9 | import Amplify 10 | 11 | class SensorValueService: NSObject, ObservableObject { 12 | 13 | // ObservedObject for iOS views to subscribe to new messages as they are received from the Cloud 14 | @Published var sensorValue: Double = 0.00 15 | @Published var sensorTime: Date = Date.now 16 | 17 | var subscription: AmplifyAsyncThrowingSequence> 18 | 19 | override init() { 20 | self.subscription = Amplify.API.subscribe(request: .onCreateSensorValue()) 21 | super.init() 22 | startSubscription() 23 | } 24 | 25 | private func startSubscription() { 26 | 27 | Task { 28 | do { 29 | for try await subscriptionEvent in self.subscription { 30 | switch subscriptionEvent { 31 | case .connection(let subscriptionConnectionState): 32 | print("Subscription connect state is \(subscriptionConnectionState)") 33 | case .data(let result): 34 | switch result { 35 | case .success(let createdSensorValue): 36 | print("Successfully received value from subscription: \(createdSensorValue)") 37 | DispatchQueue.main.async { 38 | self.sensorValue = createdSensorValue.value 39 | self.sensorTime = Date(timeIntervalSince1970: Double(createdSensorValue.timestamp / 1000)) 40 | } 41 | case .failure(let error): 42 | print("Got failed result with \(error.errorDescription)") 43 | } 44 | } 45 | } 46 | } catch { 47 | print("Subscription has terminated with \(error)") 48 | } 49 | } 50 | } 51 | 52 | func cancelSubscription() { 53 | print("Cancelling subscription") 54 | self.subscription.cancel(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /mobile/mobile/Subscriptions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Subscriptions.swift 3 | // mobile 4 | // 5 | // Created by David Moser on 12/15/24. 6 | // 7 | 8 | import Amplify 9 | 10 | // Appsync GraphQL subscription request for sensor values 11 | extension GraphQLRequest { 12 | 13 | static func onCreateSensorValue() -> GraphQLRequest { 14 | let operationName = "onCreateSensorValue" 15 | let document = """ 16 | subscription { 17 | \(operationName) { 18 | id 19 | createdAt 20 | sensorId 21 | timestamp 22 | updatedAt 23 | value 24 | } 25 | } 26 | """ 27 | 28 | return GraphQLRequest( 29 | document: document, 30 | responseType: SensorValue.self, 31 | decodePath: operationName) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /mobile/mobile/mobile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /mobile/mobile/mobileApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // mobileApp.swift 3 | // mobile 4 | // 5 | // Created by David Moser on 12/15/24. 6 | // 7 | import Amplify 8 | import Authenticator 9 | import AWSCognitoAuthPlugin 10 | import AWSAPIPlugin 11 | import SwiftUI 12 | 13 | @main 14 | struct mobileApp: App { 15 | init() { 16 | let awsApiPlugin = AWSAPIPlugin(modelRegistration: AmplifyModels()) 17 | do { 18 | try Amplify.add(plugin: AWSCognitoAuthPlugin()) 19 | try Amplify.add(plugin: awsApiPlugin) 20 | try Amplify.configure(with: .amplifyOutputs) 21 | } catch { 22 | print("Unable to configure Amplify \(error)") 23 | } 24 | } 25 | 26 | var body: some Scene { 27 | WindowGroup { 28 | Authenticator { state in 29 | ContentView() 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /mobile/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mobile", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "keywords": [], 9 | "author": "", 10 | "license": "ISC", 11 | "description": "", 12 | "devDependencies": { 13 | "@aws-amplify/backend": "^1.9.0", 14 | "@aws-amplify/backend-cli": "^1.4.3", 15 | "aws-cdk": "^2.177.0", 16 | "aws-cdk-lib": "^2.177.0", 17 | "constructs": "^10.4.2", 18 | "esbuild": "^0.24.0", 19 | "tsx": "^4.19.2", 20 | "typescript": "^5.7.2" 21 | }, 22 | "dependencies": { 23 | "@aws-sdk/protocol-http": "^3.370.0", 24 | "@aws-sdk/signature-v4": "^3.370.0", 25 | "aws-amplify": "^6.10.3" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /sensor/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # node.js 6 | # 7 | node_modules/ 8 | npm-debug.log 9 | yarn-error.log 10 | 11 | # AWS IOT thing certificates 12 | certs/*.crt 13 | certs/*.key 14 | -------------------------------------------------------------------------------- /sensor/certs/AmazonRootCA1.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF 3 | ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 4 | b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL 5 | MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv 6 | b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj 7 | ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM 8 | 9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw 9 | IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 10 | VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L 11 | 93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm 12 | jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC 13 | AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA 14 | A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI 15 | U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs 16 | N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv 17 | o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU 18 | 5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy 19 | rqXRfboQnoZsG4q5WTP468SQvvG5 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /sensor/create-sensor.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs').promises; 2 | const { 3 | IoTClient, 4 | DescribeEndpointCommand, 5 | UpdateIndexingConfigurationCommand, 6 | CreatePolicyCommand, 7 | CreateKeysAndCertificateCommand, 8 | CreateThingCommand, 9 | AttachPolicyCommand, 10 | AttachThingPrincipalCommand 11 | } = require("@aws-sdk/client-iot"); 12 | 13 | const { ArgumentParser } = require('argparse'); 14 | 15 | //constants used in the app - do not change 16 | const SETTINGS_FILE = './settings.json'; 17 | const CERT_FOLDER = './certs/'; 18 | const POLICY_FILE = './policy.json'; 19 | const ROOT_CA_FILE = 'AmazonRootCA1.pem'; 20 | 21 | //open sensor definition file 22 | var settings = require(SETTINGS_FILE); 23 | const policyDocument = require(POLICY_FILE); 24 | 25 | async function createSensor(profile, region){ 26 | 27 | try { 28 | 29 | const iotClient = new IoTClient({ profile: profile, region: region }); 30 | 31 | // get the regional IOT endpoint 32 | var params = { endpointType: 'iot:Data-ATS'}; 33 | var command = new DescribeEndpointCommand(params); 34 | const response = await iotClient.send(command); 35 | const host = response.endpointAddress; 36 | 37 | //enable thing fleet indexing to enable searching things 38 | params = { 39 | thingIndexingConfiguration: { 40 | thingIndexingMode: "REGISTRY_AND_SHADOW" 41 | } 42 | } 43 | 44 | command = new UpdateIndexingConfigurationCommand(params) 45 | var result = await iotClient.send(command) 46 | 47 | //set the iot core endpoint 48 | settings.host = host; 49 | 50 | //create the IOT policy 51 | var policyName = 'Policy-' + settings.clientId; 52 | var policy = { policyName: policyName, policyDocument: JSON.stringify(policyDocument)}; 53 | command = new CreatePolicyCommand(policy) 54 | result = await iotClient.send(command) 55 | 56 | //create the certificates 57 | command = new CreateKeysAndCertificateCommand({setAsActive:true}); 58 | result = await iotClient.send(command) 59 | settings.certificateArn = result.certificateArn; 60 | const certificatePem = result.certificatePem; 61 | const privateKey = result.keyPair.PrivateKey; 62 | 63 | //save the certificate 64 | var fileName = CERT_FOLDER + settings.clientId + '-certificate.pem.crt'; 65 | settings.certPath = fileName; 66 | await fs.writeFile(fileName, certificatePem); 67 | 68 | //save the private key 69 | fileName = CERT_FOLDER + settings.clientId + '-private.pem.key'; 70 | settings.keyPath = fileName; 71 | await fs.writeFile(fileName, privateKey); 72 | 73 | //save the AWS root certificate 74 | settings.caPath = CERT_FOLDER + ROOT_CA_FILE; 75 | 76 | //create the thing 77 | params = { 78 | thingName: settings.clientId, 79 | }; 80 | 81 | command = new CreateThingCommand(params) 82 | await iotClient.send(command) 83 | 84 | //attach policy to certificate 85 | command = new AttachPolicyCommand({ policyName: policyName, target: settings.certificateArn}) 86 | await iotClient.send(command) 87 | 88 | //attach thing to certificate 89 | command = new AttachThingPrincipalCommand({thingName: settings.clientId, principal: settings.certificateArn}) 90 | await iotClient.send(command) 91 | 92 | //save the updated settings file 93 | let data = JSON.stringify(settings, null, 2); 94 | await fs.writeFile(SETTINGS_FILE, data); 95 | 96 | //display results 97 | console.log('IoT Thing Provisioned: ' + settings.clientId); 98 | console.log('AWS Profile: ' + profile); 99 | console.log('AWS Region: ' + region); 100 | } 101 | catch (err) { 102 | 103 | console.log('Error creating sensor'); 104 | console.log(err.message); 105 | } 106 | 107 | } 108 | 109 | // parse for profile command line arguent 110 | const parser = new ArgumentParser({ 111 | description: 'Creates IoT Thing for sensor defined in settings.json' 112 | }); 113 | 114 | parser.add_argument('--profile', {default: 'default'}); 115 | parser.add_argument('--region', {default: 'us-east-1'}); 116 | 117 | args = parser.parse_args() 118 | 119 | createSensor(args.profile, args.region); 120 | -------------------------------------------------------------------------------- /sensor/delete-sensor.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs').promises; 2 | const { 3 | IoTClient, 4 | DetachThingPrincipalCommand, 5 | DeleteThingCommand, 6 | DetachPolicyCommand, 7 | DeletePolicyCommand, 8 | UpdateCertificateCommand, 9 | DeleteCertificateCommand 10 | } = require("@aws-sdk/client-iot"); 11 | 12 | const { ArgumentParser } = require('argparse'); 13 | 14 | //constants used in the app - do not change 15 | const SETTINGS_FILE = './settings.json'; 16 | 17 | //open sensor definition file 18 | var settings = require(SETTINGS_FILE); 19 | 20 | async function deleteSensor(profile, region){ 21 | 22 | try { 23 | 24 | const iotClient = new IoTClient({ profile: profile, region: region }); 25 | 26 | //remove the iot core endpoint 27 | settings.host = ""; 28 | 29 | //attach thing to certificate 30 | var command = new DetachThingPrincipalCommand({thingName: settings.clientId, principal: settings.certificateArn}) 31 | await iotClient.send(command) 32 | 33 | //delete the thing 34 | command = new DeleteThingCommand({thingName: settings.clientId}) 35 | await iotClient.send(command) 36 | 37 | //detach policy from certificate 38 | var policyName = 'Policy-' + settings.clientId; 39 | command = new DetachPolicyCommand({ policyName: policyName, target: settings.certificateArn}) 40 | await iotClient.send(command) 41 | 42 | //delete the IOT policy 43 | command = new DeletePolicyCommand({policyName: policyName}) 44 | await iotClient.send(command) 45 | 46 | //delete the certificates 47 | var certificateId = settings.certificateArn.split('/')[1]; 48 | command = new UpdateCertificateCommand({certificateId:certificateId, newStatus:"INACTIVE"}) 49 | await iotClient.send(command) 50 | 51 | command = new DeleteCertificateCommand({certificateId:certificateId, forceDelete:true}) 52 | await iotClient.send(command) 53 | settings.certificateArn = "" 54 | 55 | //delete the certificate files 56 | await fs.unlink(settings.keyPath); 57 | settings.keyPath = ""; 58 | 59 | await fs.unlink(settings.certPath); 60 | settings.certPath = ""; 61 | settings.caPath = ""; 62 | 63 | //save the updated settings file 64 | var data = JSON.stringify(settings, null, 2); 65 | await fs.writeFile(SETTINGS_FILE, data); 66 | 67 | //display results 68 | console.log('IoT Thing Removed: ' + settings.clientId); 69 | console.log('AWS Profile: ' + profile); 70 | console.log('AWS Region: ' + region); 71 | } 72 | catch (err) { 73 | 74 | console.log('Error deleting sensor'); 75 | console.log(err.message); 76 | } 77 | } 78 | 79 | // parse for profile command line arguent 80 | const parser = new ArgumentParser({ 81 | description: 'Deletes IoT Thing for sensor defined in settings.json' 82 | }); 83 | 84 | parser.add_argument('--profile', {default: 'default'}); 85 | parser.add_argument('--region', {default: 'us-east-1'}); 86 | 87 | args = parser.parse_args() 88 | 89 | deleteSensor(args.profile, args.region); 90 | -------------------------------------------------------------------------------- /sensor/index.js: -------------------------------------------------------------------------------- 1 | const awsIot = require('aws-iot-device-sdk'); 2 | 3 | //load the settings file that contains the location of the device certificates and the clientId of the sensor 4 | var settings = require('./settings.json'); 5 | 6 | //constants used in the application 7 | const SHADOW_TOPIC = "$aws/things/[thingName]/shadow/update"; 8 | const VALUE_TOPIC = "dt/sensor-view/[thingName]/sensor-value"; //topic to which sensor values will be published 9 | const VALUE_RATE = 2000; //rate in milliseconds new temperature values will be published to the Cloud 10 | 11 | //initialize the IOT device 12 | var device = awsIot.device(settings); 13 | 14 | //shadow document to be transmitted at statup 15 | var shadowDocument = { 16 | state: { 17 | reported: { 18 | sensorType: "Temperature", 19 | } 20 | } 21 | } 22 | 23 | //create a placeholder for the message 24 | var msg = { 25 | value: 0, 26 | timestamp: new Date().getTime() 27 | } 28 | 29 | device.on('connect', function() { 30 | 31 | console.log('connected to IoT Hub'); 32 | 33 | //publish the shadow document for the sensor 34 | var topic = SHADOW_TOPIC.replace('[thingName]', settings.clientId); 35 | 36 | device.publish(topic, JSON.stringify(shadowDocument)); 37 | 38 | console.log('published to shadow topic ' + topic + ' ' + JSON.stringify(shadowDocument)); 39 | 40 | //publish new value readings based on value_rate 41 | setInterval(function(){ 42 | 43 | msg.value = 75 + Math.floor((Math.random() * (10 - 1) + 1)); 44 | msg.timestamp = new Date().getTime(); 45 | 46 | var topic = VALUE_TOPIC.replace('[thingName]', settings.clientId); 47 | 48 | device.publish(topic, JSON.stringify(msg)); 49 | 50 | console.log('published to topic ' + topic + ' ' + JSON.stringify(msg)); 51 | 52 | 53 | }, VALUE_RATE); 54 | }); 55 | 56 | device.on('error', function(error) { 57 | console.log('Error: ', error); 58 | }); 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /sensor/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aws-appsync-iot-core-realtime-sensor", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "aws-appsync-iot-core-realtime-sensor", 9 | "version": "1.0.0", 10 | "license": "MIT-0", 11 | "dependencies": { 12 | "@aws-sdk/client-iot": "^3.708.0", 13 | "argparse": "^2.0.1", 14 | "aws-iot-device-sdk": "^2.2.15" 15 | } 16 | }, 17 | "node_modules/@aws-crypto/sha256-browser": { 18 | "version": "5.2.0", 19 | "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", 20 | "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", 21 | "license": "Apache-2.0", 22 | "dependencies": { 23 | "@aws-crypto/sha256-js": "^5.2.0", 24 | "@aws-crypto/supports-web-crypto": "^5.2.0", 25 | "@aws-crypto/util": "^5.2.0", 26 | "@aws-sdk/types": "^3.222.0", 27 | "@aws-sdk/util-locate-window": "^3.0.0", 28 | "@smithy/util-utf8": "^2.0.0", 29 | "tslib": "^2.6.2" 30 | } 31 | }, 32 | "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { 33 | "version": "2.2.0", 34 | "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", 35 | "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", 36 | "license": "Apache-2.0", 37 | "dependencies": { 38 | "tslib": "^2.6.2" 39 | }, 40 | "engines": { 41 | "node": ">=14.0.0" 42 | } 43 | }, 44 | "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { 45 | "version": "2.2.0", 46 | "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", 47 | "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", 48 | "license": "Apache-2.0", 49 | "dependencies": { 50 | "@smithy/is-array-buffer": "^2.2.0", 51 | "tslib": "^2.6.2" 52 | }, 53 | "engines": { 54 | "node": ">=14.0.0" 55 | } 56 | }, 57 | "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { 58 | "version": "2.3.0", 59 | "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", 60 | "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", 61 | "license": "Apache-2.0", 62 | "dependencies": { 63 | "@smithy/util-buffer-from": "^2.2.0", 64 | "tslib": "^2.6.2" 65 | }, 66 | "engines": { 67 | "node": ">=14.0.0" 68 | } 69 | }, 70 | "node_modules/@aws-crypto/sha256-js": { 71 | "version": "5.2.0", 72 | "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", 73 | "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", 74 | "license": "Apache-2.0", 75 | "dependencies": { 76 | "@aws-crypto/util": "^5.2.0", 77 | "@aws-sdk/types": "^3.222.0", 78 | "tslib": "^2.6.2" 79 | }, 80 | "engines": { 81 | "node": ">=16.0.0" 82 | } 83 | }, 84 | "node_modules/@aws-crypto/supports-web-crypto": { 85 | "version": "5.2.0", 86 | "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", 87 | "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", 88 | "license": "Apache-2.0", 89 | "dependencies": { 90 | "tslib": "^2.6.2" 91 | } 92 | }, 93 | "node_modules/@aws-crypto/util": { 94 | "version": "5.2.0", 95 | "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", 96 | "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", 97 | "license": "Apache-2.0", 98 | "dependencies": { 99 | "@aws-sdk/types": "^3.222.0", 100 | "@smithy/util-utf8": "^2.0.0", 101 | "tslib": "^2.6.2" 102 | } 103 | }, 104 | "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { 105 | "version": "2.2.0", 106 | "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", 107 | "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", 108 | "license": "Apache-2.0", 109 | "dependencies": { 110 | "tslib": "^2.6.2" 111 | }, 112 | "engines": { 113 | "node": ">=14.0.0" 114 | } 115 | }, 116 | "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { 117 | "version": "2.2.0", 118 | "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", 119 | "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", 120 | "license": "Apache-2.0", 121 | "dependencies": { 122 | "@smithy/is-array-buffer": "^2.2.0", 123 | "tslib": "^2.6.2" 124 | }, 125 | "engines": { 126 | "node": ">=14.0.0" 127 | } 128 | }, 129 | "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { 130 | "version": "2.3.0", 131 | "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", 132 | "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", 133 | "license": "Apache-2.0", 134 | "dependencies": { 135 | "@smithy/util-buffer-from": "^2.2.0", 136 | "tslib": "^2.6.2" 137 | }, 138 | "engines": { 139 | "node": ">=14.0.0" 140 | } 141 | }, 142 | "node_modules/@aws-sdk/client-iot": { 143 | "version": "3.712.0", 144 | "resolved": "https://registry.npmjs.org/@aws-sdk/client-iot/-/client-iot-3.712.0.tgz", 145 | "integrity": "sha512-hFPmAwoAE2TBs5IFbK0Fg79aTfM6aUzQz9GGnm6+0wVjOjQ+vx/jPISDMP3XAzeb5X3RLpJZEe9Zzj6tEi/pOA==", 146 | "license": "Apache-2.0", 147 | "dependencies": { 148 | "@aws-crypto/sha256-browser": "5.2.0", 149 | "@aws-crypto/sha256-js": "5.2.0", 150 | "@aws-sdk/client-sso-oidc": "3.712.0", 151 | "@aws-sdk/client-sts": "3.712.0", 152 | "@aws-sdk/core": "3.709.0", 153 | "@aws-sdk/credential-provider-node": "3.712.0", 154 | "@aws-sdk/middleware-host-header": "3.709.0", 155 | "@aws-sdk/middleware-logger": "3.709.0", 156 | "@aws-sdk/middleware-recursion-detection": "3.709.0", 157 | "@aws-sdk/middleware-user-agent": "3.709.0", 158 | "@aws-sdk/region-config-resolver": "3.709.0", 159 | "@aws-sdk/types": "3.709.0", 160 | "@aws-sdk/util-endpoints": "3.709.0", 161 | "@aws-sdk/util-user-agent-browser": "3.709.0", 162 | "@aws-sdk/util-user-agent-node": "3.712.0", 163 | "@smithy/config-resolver": "^3.0.13", 164 | "@smithy/core": "^2.5.5", 165 | "@smithy/fetch-http-handler": "^4.1.2", 166 | "@smithy/hash-node": "^3.0.11", 167 | "@smithy/invalid-dependency": "^3.0.11", 168 | "@smithy/middleware-content-length": "^3.0.13", 169 | "@smithy/middleware-endpoint": "^3.2.5", 170 | "@smithy/middleware-retry": "^3.0.30", 171 | "@smithy/middleware-serde": "^3.0.11", 172 | "@smithy/middleware-stack": "^3.0.11", 173 | "@smithy/node-config-provider": "^3.1.12", 174 | "@smithy/node-http-handler": "^3.3.2", 175 | "@smithy/protocol-http": "^4.1.8", 176 | "@smithy/smithy-client": "^3.5.0", 177 | "@smithy/types": "^3.7.2", 178 | "@smithy/url-parser": "^3.0.11", 179 | "@smithy/util-base64": "^3.0.0", 180 | "@smithy/util-body-length-browser": "^3.0.0", 181 | "@smithy/util-body-length-node": "^3.0.0", 182 | "@smithy/util-defaults-mode-browser": "^3.0.30", 183 | "@smithy/util-defaults-mode-node": "^3.0.30", 184 | "@smithy/util-endpoints": "^2.1.7", 185 | "@smithy/util-middleware": "^3.0.11", 186 | "@smithy/util-retry": "^3.0.11", 187 | "@smithy/util-utf8": "^3.0.0", 188 | "@types/uuid": "^9.0.1", 189 | "tslib": "^2.6.2", 190 | "uuid": "^9.0.1" 191 | }, 192 | "engines": { 193 | "node": ">=16.0.0" 194 | } 195 | }, 196 | "node_modules/@aws-sdk/client-sso": { 197 | "version": "3.712.0", 198 | "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.712.0.tgz", 199 | "integrity": "sha512-tBo/eW3YpZ9f3Q1qA7aA8uliNFJJX0OP7R2IUJ8t6rqVTk15wWCEPNmXzUZKgruDnKUfCaF4+r9q/Yy4fBc9PA==", 200 | "license": "Apache-2.0", 201 | "dependencies": { 202 | "@aws-crypto/sha256-browser": "5.2.0", 203 | "@aws-crypto/sha256-js": "5.2.0", 204 | "@aws-sdk/core": "3.709.0", 205 | "@aws-sdk/middleware-host-header": "3.709.0", 206 | "@aws-sdk/middleware-logger": "3.709.0", 207 | "@aws-sdk/middleware-recursion-detection": "3.709.0", 208 | "@aws-sdk/middleware-user-agent": "3.709.0", 209 | "@aws-sdk/region-config-resolver": "3.709.0", 210 | "@aws-sdk/types": "3.709.0", 211 | "@aws-sdk/util-endpoints": "3.709.0", 212 | "@aws-sdk/util-user-agent-browser": "3.709.0", 213 | "@aws-sdk/util-user-agent-node": "3.712.0", 214 | "@smithy/config-resolver": "^3.0.13", 215 | "@smithy/core": "^2.5.5", 216 | "@smithy/fetch-http-handler": "^4.1.2", 217 | "@smithy/hash-node": "^3.0.11", 218 | "@smithy/invalid-dependency": "^3.0.11", 219 | "@smithy/middleware-content-length": "^3.0.13", 220 | "@smithy/middleware-endpoint": "^3.2.5", 221 | "@smithy/middleware-retry": "^3.0.30", 222 | "@smithy/middleware-serde": "^3.0.11", 223 | "@smithy/middleware-stack": "^3.0.11", 224 | "@smithy/node-config-provider": "^3.1.12", 225 | "@smithy/node-http-handler": "^3.3.2", 226 | "@smithy/protocol-http": "^4.1.8", 227 | "@smithy/smithy-client": "^3.5.0", 228 | "@smithy/types": "^3.7.2", 229 | "@smithy/url-parser": "^3.0.11", 230 | "@smithy/util-base64": "^3.0.0", 231 | "@smithy/util-body-length-browser": "^3.0.0", 232 | "@smithy/util-body-length-node": "^3.0.0", 233 | "@smithy/util-defaults-mode-browser": "^3.0.30", 234 | "@smithy/util-defaults-mode-node": "^3.0.30", 235 | "@smithy/util-endpoints": "^2.1.7", 236 | "@smithy/util-middleware": "^3.0.11", 237 | "@smithy/util-retry": "^3.0.11", 238 | "@smithy/util-utf8": "^3.0.0", 239 | "tslib": "^2.6.2" 240 | }, 241 | "engines": { 242 | "node": ">=16.0.0" 243 | } 244 | }, 245 | "node_modules/@aws-sdk/client-sso-oidc": { 246 | "version": "3.712.0", 247 | "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.712.0.tgz", 248 | "integrity": "sha512-xNFrG9syrG6pxUP7Ld/nu3afQ9+rbJM9qrE+wDNz4VnNZ3vLiJty4fH85zBFhOQ5OF2DIJTWsFzXGi2FYjsCMA==", 249 | "license": "Apache-2.0", 250 | "dependencies": { 251 | "@aws-crypto/sha256-browser": "5.2.0", 252 | "@aws-crypto/sha256-js": "5.2.0", 253 | "@aws-sdk/core": "3.709.0", 254 | "@aws-sdk/credential-provider-node": "3.712.0", 255 | "@aws-sdk/middleware-host-header": "3.709.0", 256 | "@aws-sdk/middleware-logger": "3.709.0", 257 | "@aws-sdk/middleware-recursion-detection": "3.709.0", 258 | "@aws-sdk/middleware-user-agent": "3.709.0", 259 | "@aws-sdk/region-config-resolver": "3.709.0", 260 | "@aws-sdk/types": "3.709.0", 261 | "@aws-sdk/util-endpoints": "3.709.0", 262 | "@aws-sdk/util-user-agent-browser": "3.709.0", 263 | "@aws-sdk/util-user-agent-node": "3.712.0", 264 | "@smithy/config-resolver": "^3.0.13", 265 | "@smithy/core": "^2.5.5", 266 | "@smithy/fetch-http-handler": "^4.1.2", 267 | "@smithy/hash-node": "^3.0.11", 268 | "@smithy/invalid-dependency": "^3.0.11", 269 | "@smithy/middleware-content-length": "^3.0.13", 270 | "@smithy/middleware-endpoint": "^3.2.5", 271 | "@smithy/middleware-retry": "^3.0.30", 272 | "@smithy/middleware-serde": "^3.0.11", 273 | "@smithy/middleware-stack": "^3.0.11", 274 | "@smithy/node-config-provider": "^3.1.12", 275 | "@smithy/node-http-handler": "^3.3.2", 276 | "@smithy/protocol-http": "^4.1.8", 277 | "@smithy/smithy-client": "^3.5.0", 278 | "@smithy/types": "^3.7.2", 279 | "@smithy/url-parser": "^3.0.11", 280 | "@smithy/util-base64": "^3.0.0", 281 | "@smithy/util-body-length-browser": "^3.0.0", 282 | "@smithy/util-body-length-node": "^3.0.0", 283 | "@smithy/util-defaults-mode-browser": "^3.0.30", 284 | "@smithy/util-defaults-mode-node": "^3.0.30", 285 | "@smithy/util-endpoints": "^2.1.7", 286 | "@smithy/util-middleware": "^3.0.11", 287 | "@smithy/util-retry": "^3.0.11", 288 | "@smithy/util-utf8": "^3.0.0", 289 | "tslib": "^2.6.2" 290 | }, 291 | "engines": { 292 | "node": ">=16.0.0" 293 | }, 294 | "peerDependencies": { 295 | "@aws-sdk/client-sts": "^3.712.0" 296 | } 297 | }, 298 | "node_modules/@aws-sdk/client-sts": { 299 | "version": "3.712.0", 300 | "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.712.0.tgz", 301 | "integrity": "sha512-gIO6BD+hkEe3GKQhbiFP0zcNQv0EkP1Cl9SOstxS+X9CeudEgVX/xEPUjyoFVkfkntPBJ1g0I1u5xOzzRExl4g==", 302 | "license": "Apache-2.0", 303 | "dependencies": { 304 | "@aws-crypto/sha256-browser": "5.2.0", 305 | "@aws-crypto/sha256-js": "5.2.0", 306 | "@aws-sdk/client-sso-oidc": "3.712.0", 307 | "@aws-sdk/core": "3.709.0", 308 | "@aws-sdk/credential-provider-node": "3.712.0", 309 | "@aws-sdk/middleware-host-header": "3.709.0", 310 | "@aws-sdk/middleware-logger": "3.709.0", 311 | "@aws-sdk/middleware-recursion-detection": "3.709.0", 312 | "@aws-sdk/middleware-user-agent": "3.709.0", 313 | "@aws-sdk/region-config-resolver": "3.709.0", 314 | "@aws-sdk/types": "3.709.0", 315 | "@aws-sdk/util-endpoints": "3.709.0", 316 | "@aws-sdk/util-user-agent-browser": "3.709.0", 317 | "@aws-sdk/util-user-agent-node": "3.712.0", 318 | "@smithy/config-resolver": "^3.0.13", 319 | "@smithy/core": "^2.5.5", 320 | "@smithy/fetch-http-handler": "^4.1.2", 321 | "@smithy/hash-node": "^3.0.11", 322 | "@smithy/invalid-dependency": "^3.0.11", 323 | "@smithy/middleware-content-length": "^3.0.13", 324 | "@smithy/middleware-endpoint": "^3.2.5", 325 | "@smithy/middleware-retry": "^3.0.30", 326 | "@smithy/middleware-serde": "^3.0.11", 327 | "@smithy/middleware-stack": "^3.0.11", 328 | "@smithy/node-config-provider": "^3.1.12", 329 | "@smithy/node-http-handler": "^3.3.2", 330 | "@smithy/protocol-http": "^4.1.8", 331 | "@smithy/smithy-client": "^3.5.0", 332 | "@smithy/types": "^3.7.2", 333 | "@smithy/url-parser": "^3.0.11", 334 | "@smithy/util-base64": "^3.0.0", 335 | "@smithy/util-body-length-browser": "^3.0.0", 336 | "@smithy/util-body-length-node": "^3.0.0", 337 | "@smithy/util-defaults-mode-browser": "^3.0.30", 338 | "@smithy/util-defaults-mode-node": "^3.0.30", 339 | "@smithy/util-endpoints": "^2.1.7", 340 | "@smithy/util-middleware": "^3.0.11", 341 | "@smithy/util-retry": "^3.0.11", 342 | "@smithy/util-utf8": "^3.0.0", 343 | "tslib": "^2.6.2" 344 | }, 345 | "engines": { 346 | "node": ">=16.0.0" 347 | } 348 | }, 349 | "node_modules/@aws-sdk/core": { 350 | "version": "3.709.0", 351 | "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.709.0.tgz", 352 | "integrity": "sha512-7kuSpzdOTAE026j85wq/fN9UDZ70n0OHw81vFqMWwlEFtm5IQ/MRCLKcC4HkXxTdfy1PqFlmoXxWqeBa15tujw==", 353 | "license": "Apache-2.0", 354 | "dependencies": { 355 | "@aws-sdk/types": "3.709.0", 356 | "@smithy/core": "^2.5.5", 357 | "@smithy/node-config-provider": "^3.1.12", 358 | "@smithy/property-provider": "^3.1.11", 359 | "@smithy/protocol-http": "^4.1.8", 360 | "@smithy/signature-v4": "^4.2.4", 361 | "@smithy/smithy-client": "^3.5.0", 362 | "@smithy/types": "^3.7.2", 363 | "@smithy/util-middleware": "^3.0.11", 364 | "fast-xml-parser": "4.4.1", 365 | "tslib": "^2.6.2" 366 | }, 367 | "engines": { 368 | "node": ">=16.0.0" 369 | } 370 | }, 371 | "node_modules/@aws-sdk/credential-provider-env": { 372 | "version": "3.709.0", 373 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.709.0.tgz", 374 | "integrity": "sha512-ZMAp9LSikvHDFVa84dKpQmow6wsg956Um20cKuioPpX2GGreJFur7oduD+tRJT6FtIOHn+64YH+0MwiXLhsaIQ==", 375 | "license": "Apache-2.0", 376 | "dependencies": { 377 | "@aws-sdk/core": "3.709.0", 378 | "@aws-sdk/types": "3.709.0", 379 | "@smithy/property-provider": "^3.1.11", 380 | "@smithy/types": "^3.7.2", 381 | "tslib": "^2.6.2" 382 | }, 383 | "engines": { 384 | "node": ">=16.0.0" 385 | } 386 | }, 387 | "node_modules/@aws-sdk/credential-provider-http": { 388 | "version": "3.709.0", 389 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.709.0.tgz", 390 | "integrity": "sha512-lIS7XLwCOyJnLD70f+VIRr8DNV1HPQe9oN6aguYrhoczqz7vDiVZLe3lh714cJqq9rdxzFypK5DqKHmcscMEPQ==", 391 | "license": "Apache-2.0", 392 | "dependencies": { 393 | "@aws-sdk/core": "3.709.0", 394 | "@aws-sdk/types": "3.709.0", 395 | "@smithy/fetch-http-handler": "^4.1.2", 396 | "@smithy/node-http-handler": "^3.3.2", 397 | "@smithy/property-provider": "^3.1.11", 398 | "@smithy/protocol-http": "^4.1.8", 399 | "@smithy/smithy-client": "^3.5.0", 400 | "@smithy/types": "^3.7.2", 401 | "@smithy/util-stream": "^3.3.2", 402 | "tslib": "^2.6.2" 403 | }, 404 | "engines": { 405 | "node": ">=16.0.0" 406 | } 407 | }, 408 | "node_modules/@aws-sdk/credential-provider-ini": { 409 | "version": "3.712.0", 410 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.712.0.tgz", 411 | "integrity": "sha512-sTsdQ/Fm/suqMdpjhMuss/5uKL18vcuWnNTQVrG9iGNRqZLbq65MXquwbUpgzfoUmIcH+4CrY6H2ebpTIECIag==", 412 | "license": "Apache-2.0", 413 | "dependencies": { 414 | "@aws-sdk/core": "3.709.0", 415 | "@aws-sdk/credential-provider-env": "3.709.0", 416 | "@aws-sdk/credential-provider-http": "3.709.0", 417 | "@aws-sdk/credential-provider-process": "3.709.0", 418 | "@aws-sdk/credential-provider-sso": "3.712.0", 419 | "@aws-sdk/credential-provider-web-identity": "3.709.0", 420 | "@aws-sdk/types": "3.709.0", 421 | "@smithy/credential-provider-imds": "^3.2.8", 422 | "@smithy/property-provider": "^3.1.11", 423 | "@smithy/shared-ini-file-loader": "^3.1.12", 424 | "@smithy/types": "^3.7.2", 425 | "tslib": "^2.6.2" 426 | }, 427 | "engines": { 428 | "node": ">=16.0.0" 429 | }, 430 | "peerDependencies": { 431 | "@aws-sdk/client-sts": "^3.712.0" 432 | } 433 | }, 434 | "node_modules/@aws-sdk/credential-provider-node": { 435 | "version": "3.712.0", 436 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.712.0.tgz", 437 | "integrity": "sha512-gXrHymW3rMRYORkPVQwL8Gi5Lu92F16SoZR543x03qCi7rm00oL9tRD85ACxkhprS1Wh8lUIUMNoeiwnYWTNuQ==", 438 | "license": "Apache-2.0", 439 | "dependencies": { 440 | "@aws-sdk/credential-provider-env": "3.709.0", 441 | "@aws-sdk/credential-provider-http": "3.709.0", 442 | "@aws-sdk/credential-provider-ini": "3.712.0", 443 | "@aws-sdk/credential-provider-process": "3.709.0", 444 | "@aws-sdk/credential-provider-sso": "3.712.0", 445 | "@aws-sdk/credential-provider-web-identity": "3.709.0", 446 | "@aws-sdk/types": "3.709.0", 447 | "@smithy/credential-provider-imds": "^3.2.8", 448 | "@smithy/property-provider": "^3.1.11", 449 | "@smithy/shared-ini-file-loader": "^3.1.12", 450 | "@smithy/types": "^3.7.2", 451 | "tslib": "^2.6.2" 452 | }, 453 | "engines": { 454 | "node": ">=16.0.0" 455 | } 456 | }, 457 | "node_modules/@aws-sdk/credential-provider-process": { 458 | "version": "3.709.0", 459 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.709.0.tgz", 460 | "integrity": "sha512-IAC+jPlGQII6jhIylHOwh3RgSobqlgL59nw2qYTURr8hMCI0Z1p5y2ee646HTVt4WeCYyzUAXfxr6YI/Vitv+Q==", 461 | "license": "Apache-2.0", 462 | "dependencies": { 463 | "@aws-sdk/core": "3.709.0", 464 | "@aws-sdk/types": "3.709.0", 465 | "@smithy/property-provider": "^3.1.11", 466 | "@smithy/shared-ini-file-loader": "^3.1.12", 467 | "@smithy/types": "^3.7.2", 468 | "tslib": "^2.6.2" 469 | }, 470 | "engines": { 471 | "node": ">=16.0.0" 472 | } 473 | }, 474 | "node_modules/@aws-sdk/credential-provider-sso": { 475 | "version": "3.712.0", 476 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.712.0.tgz", 477 | "integrity": "sha512-8lCMxY7Lb9VK9qdlNXRJXE3W1UDVURnJZ3a4XWYNY6yr1TfQaN40mMyXX1oNlXXJtMV0szRvjM8dZj37E/ESAw==", 478 | "license": "Apache-2.0", 479 | "dependencies": { 480 | "@aws-sdk/client-sso": "3.712.0", 481 | "@aws-sdk/core": "3.709.0", 482 | "@aws-sdk/token-providers": "3.709.0", 483 | "@aws-sdk/types": "3.709.0", 484 | "@smithy/property-provider": "^3.1.11", 485 | "@smithy/shared-ini-file-loader": "^3.1.12", 486 | "@smithy/types": "^3.7.2", 487 | "tslib": "^2.6.2" 488 | }, 489 | "engines": { 490 | "node": ">=16.0.0" 491 | } 492 | }, 493 | "node_modules/@aws-sdk/credential-provider-web-identity": { 494 | "version": "3.709.0", 495 | "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.709.0.tgz", 496 | "integrity": "sha512-2lbDfE0IQ6gma/7BB2JpkjW5G0wGe4AS0x80oybYAYYviJmUtIR3Cn2pXun6bnAWElt4wYKl4su7oC36rs5rNA==", 497 | "license": "Apache-2.0", 498 | "dependencies": { 499 | "@aws-sdk/core": "3.709.0", 500 | "@aws-sdk/types": "3.709.0", 501 | "@smithy/property-provider": "^3.1.11", 502 | "@smithy/types": "^3.7.2", 503 | "tslib": "^2.6.2" 504 | }, 505 | "engines": { 506 | "node": ">=16.0.0" 507 | }, 508 | "peerDependencies": { 509 | "@aws-sdk/client-sts": "^3.709.0" 510 | } 511 | }, 512 | "node_modules/@aws-sdk/middleware-host-header": { 513 | "version": "3.709.0", 514 | "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.709.0.tgz", 515 | "integrity": "sha512-8gQYCYAaIw4lOCd5WYdf15Y/61MgRsAnrb2eiTl+icMlUOOzl8aOl5iDwm/Idp0oHZTflwxM4XSvGXO83PRWcw==", 516 | "license": "Apache-2.0", 517 | "dependencies": { 518 | "@aws-sdk/types": "3.709.0", 519 | "@smithy/protocol-http": "^4.1.8", 520 | "@smithy/types": "^3.7.2", 521 | "tslib": "^2.6.2" 522 | }, 523 | "engines": { 524 | "node": ">=16.0.0" 525 | } 526 | }, 527 | "node_modules/@aws-sdk/middleware-logger": { 528 | "version": "3.709.0", 529 | "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.709.0.tgz", 530 | "integrity": "sha512-jDoGSccXv9zebnpUoisjWd5u5ZPIalrmm6TjvPzZ8UqzQt3Beiz0tnQwmxQD6KRc7ADweWP5Ntiqzbw9xpVajg==", 531 | "license": "Apache-2.0", 532 | "dependencies": { 533 | "@aws-sdk/types": "3.709.0", 534 | "@smithy/types": "^3.7.2", 535 | "tslib": "^2.6.2" 536 | }, 537 | "engines": { 538 | "node": ">=16.0.0" 539 | } 540 | }, 541 | "node_modules/@aws-sdk/middleware-recursion-detection": { 542 | "version": "3.709.0", 543 | "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.709.0.tgz", 544 | "integrity": "sha512-PObL/wLr4lkfbQ0yXUWaoCWu/jcwfwZzCjsUiXW/H6hW9b/00enZxmx7OhtJYaR6xmh/Lcx5wbhIoDCbzdv0tw==", 545 | "license": "Apache-2.0", 546 | "dependencies": { 547 | "@aws-sdk/types": "3.709.0", 548 | "@smithy/protocol-http": "^4.1.8", 549 | "@smithy/types": "^3.7.2", 550 | "tslib": "^2.6.2" 551 | }, 552 | "engines": { 553 | "node": ">=16.0.0" 554 | } 555 | }, 556 | "node_modules/@aws-sdk/middleware-user-agent": { 557 | "version": "3.709.0", 558 | "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.709.0.tgz", 559 | "integrity": "sha512-ooc9ZJvgkjPhi9q05XwSfNTXkEBEIfL4hleo5rQBKwHG3aTHvwOM7LLzhdX56QZVa6sorPBp6fwULuRDSqiQHw==", 560 | "license": "Apache-2.0", 561 | "dependencies": { 562 | "@aws-sdk/core": "3.709.0", 563 | "@aws-sdk/types": "3.709.0", 564 | "@aws-sdk/util-endpoints": "3.709.0", 565 | "@smithy/core": "^2.5.5", 566 | "@smithy/protocol-http": "^4.1.8", 567 | "@smithy/types": "^3.7.2", 568 | "tslib": "^2.6.2" 569 | }, 570 | "engines": { 571 | "node": ">=16.0.0" 572 | } 573 | }, 574 | "node_modules/@aws-sdk/region-config-resolver": { 575 | "version": "3.709.0", 576 | "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.709.0.tgz", 577 | "integrity": "sha512-/NoCAMEVKAg3kBKOrNtgOfL+ECt6nrl+L7q2SyYmrcY4tVCmwuECVqewQaHc03fTnJijfKLccw0Fj+6wOCnB6w==", 578 | "license": "Apache-2.0", 579 | "dependencies": { 580 | "@aws-sdk/types": "3.709.0", 581 | "@smithy/node-config-provider": "^3.1.12", 582 | "@smithy/types": "^3.7.2", 583 | "@smithy/util-config-provider": "^3.0.0", 584 | "@smithy/util-middleware": "^3.0.11", 585 | "tslib": "^2.6.2" 586 | }, 587 | "engines": { 588 | "node": ">=16.0.0" 589 | } 590 | }, 591 | "node_modules/@aws-sdk/token-providers": { 592 | "version": "3.709.0", 593 | "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.709.0.tgz", 594 | "integrity": "sha512-q5Ar6k71nci43IbULFgC8a89d/3EHpmd7HvBzqVGRcHnoPwh8eZDBfbBXKH83NGwcS1qPSRYiDbVfeWPm4/1jA==", 595 | "license": "Apache-2.0", 596 | "dependencies": { 597 | "@aws-sdk/types": "3.709.0", 598 | "@smithy/property-provider": "^3.1.11", 599 | "@smithy/shared-ini-file-loader": "^3.1.12", 600 | "@smithy/types": "^3.7.2", 601 | "tslib": "^2.6.2" 602 | }, 603 | "engines": { 604 | "node": ">=16.0.0" 605 | }, 606 | "peerDependencies": { 607 | "@aws-sdk/client-sso-oidc": "^3.709.0" 608 | } 609 | }, 610 | "node_modules/@aws-sdk/types": { 611 | "version": "3.709.0", 612 | "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.709.0.tgz", 613 | "integrity": "sha512-ArtLTMxgjf13Kfu3gWH3Ez9Q5TkDdcRZUofpKH3pMGB/C6KAbeSCtIIDKfoRTUABzyGlPyCrZdnFjKyH+ypIpg==", 614 | "license": "Apache-2.0", 615 | "dependencies": { 616 | "@smithy/types": "^3.7.2", 617 | "tslib": "^2.6.2" 618 | }, 619 | "engines": { 620 | "node": ">=16.0.0" 621 | } 622 | }, 623 | "node_modules/@aws-sdk/util-endpoints": { 624 | "version": "3.709.0", 625 | "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.709.0.tgz", 626 | "integrity": "sha512-Mbc7AtL5WGCTKC16IGeUTz+sjpC3ptBda2t0CcK0kMVw3THDdcSq6ZlNKO747cNqdbwUvW34oHteUiHv4/z88Q==", 627 | "license": "Apache-2.0", 628 | "dependencies": { 629 | "@aws-sdk/types": "3.709.0", 630 | "@smithy/types": "^3.7.2", 631 | "@smithy/util-endpoints": "^2.1.7", 632 | "tslib": "^2.6.2" 633 | }, 634 | "engines": { 635 | "node": ">=16.0.0" 636 | } 637 | }, 638 | "node_modules/@aws-sdk/util-locate-window": { 639 | "version": "3.693.0", 640 | "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.693.0.tgz", 641 | "integrity": "sha512-ttrag6haJLWABhLqtg1Uf+4LgHWIMOVSYL+VYZmAp2v4PUGOwWmWQH0Zk8RM7YuQcLfH/EoR72/Yxz6A4FKcuw==", 642 | "license": "Apache-2.0", 643 | "dependencies": { 644 | "tslib": "^2.6.2" 645 | }, 646 | "engines": { 647 | "node": ">=16.0.0" 648 | } 649 | }, 650 | "node_modules/@aws-sdk/util-user-agent-browser": { 651 | "version": "3.709.0", 652 | "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.709.0.tgz", 653 | "integrity": "sha512-/rL2GasJzdTWUURCQKFldw2wqBtY4k4kCiA2tVZSKg3y4Ey7zO34SW8ebaeCE2/xoWOyLR2/etdKyphoo4Zrtg==", 654 | "license": "Apache-2.0", 655 | "dependencies": { 656 | "@aws-sdk/types": "3.709.0", 657 | "@smithy/types": "^3.7.2", 658 | "bowser": "^2.11.0", 659 | "tslib": "^2.6.2" 660 | } 661 | }, 662 | "node_modules/@aws-sdk/util-user-agent-node": { 663 | "version": "3.712.0", 664 | "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.712.0.tgz", 665 | "integrity": "sha512-26X21bZ4FWsVpqs33uOXiB60TOWQdVlr7T7XONDFL/XN7GEpUJkWuuIB4PTok6VOmh1viYcdxZQqekXPuzXexQ==", 666 | "license": "Apache-2.0", 667 | "dependencies": { 668 | "@aws-sdk/middleware-user-agent": "3.709.0", 669 | "@aws-sdk/types": "3.709.0", 670 | "@smithy/node-config-provider": "^3.1.12", 671 | "@smithy/types": "^3.7.2", 672 | "tslib": "^2.6.2" 673 | }, 674 | "engines": { 675 | "node": ">=16.0.0" 676 | }, 677 | "peerDependencies": { 678 | "aws-crt": ">=1.0.0" 679 | }, 680 | "peerDependenciesMeta": { 681 | "aws-crt": { 682 | "optional": true 683 | } 684 | } 685 | }, 686 | "node_modules/@httptoolkit/websocket-stream": { 687 | "version": "6.0.1", 688 | "resolved": "https://registry.npmjs.org/@httptoolkit/websocket-stream/-/websocket-stream-6.0.1.tgz", 689 | "integrity": "sha512-A0NOZI+Glp3Xgcz6Na7i7o09+/+xm2m0UCU8gdtM2nIv6/cjLmhMZMqehSpTlgbx9omtLmV8LVqOskPEyWnmZQ==", 690 | "license": "BSD-2-Clause", 691 | "dependencies": { 692 | "@types/ws": "*", 693 | "duplexify": "^3.5.1", 694 | "inherits": "^2.0.1", 695 | "isomorphic-ws": "^4.0.1", 696 | "readable-stream": "^2.3.3", 697 | "safe-buffer": "^5.1.2", 698 | "ws": "*", 699 | "xtend": "^4.0.0" 700 | } 701 | }, 702 | "node_modules/@smithy/abort-controller": { 703 | "version": "3.1.9", 704 | "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.9.tgz", 705 | "integrity": "sha512-yiW0WI30zj8ZKoSYNx90no7ugVn3khlyH/z5W8qtKBtVE6awRALbhSG+2SAHA1r6bO/6M9utxYKVZ3PCJ1rWxw==", 706 | "license": "Apache-2.0", 707 | "dependencies": { 708 | "@smithy/types": "^3.7.2", 709 | "tslib": "^2.6.2" 710 | }, 711 | "engines": { 712 | "node": ">=16.0.0" 713 | } 714 | }, 715 | "node_modules/@smithy/config-resolver": { 716 | "version": "3.0.13", 717 | "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.13.tgz", 718 | "integrity": "sha512-Gr/qwzyPaTL1tZcq8WQyHhTZREER5R1Wytmz4WnVGL4onA3dNk6Btll55c8Vr58pLdvWZmtG8oZxJTw3t3q7Jg==", 719 | "license": "Apache-2.0", 720 | "dependencies": { 721 | "@smithy/node-config-provider": "^3.1.12", 722 | "@smithy/types": "^3.7.2", 723 | "@smithy/util-config-provider": "^3.0.0", 724 | "@smithy/util-middleware": "^3.0.11", 725 | "tslib": "^2.6.2" 726 | }, 727 | "engines": { 728 | "node": ">=16.0.0" 729 | } 730 | }, 731 | "node_modules/@smithy/core": { 732 | "version": "2.5.5", 733 | "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.5.5.tgz", 734 | "integrity": "sha512-G8G/sDDhXA7o0bOvkc7bgai6POuSld/+XhNnWAbpQTpLv2OZPvyqQ58tLPPlz0bSNsXktldDDREIv1LczFeNEw==", 735 | "license": "Apache-2.0", 736 | "dependencies": { 737 | "@smithy/middleware-serde": "^3.0.11", 738 | "@smithy/protocol-http": "^4.1.8", 739 | "@smithy/types": "^3.7.2", 740 | "@smithy/util-body-length-browser": "^3.0.0", 741 | "@smithy/util-middleware": "^3.0.11", 742 | "@smithy/util-stream": "^3.3.2", 743 | "@smithy/util-utf8": "^3.0.0", 744 | "tslib": "^2.6.2" 745 | }, 746 | "engines": { 747 | "node": ">=16.0.0" 748 | } 749 | }, 750 | "node_modules/@smithy/credential-provider-imds": { 751 | "version": "3.2.8", 752 | "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.8.tgz", 753 | "integrity": "sha512-ZCY2yD0BY+K9iMXkkbnjo+08T2h8/34oHd0Jmh6BZUSZwaaGlGCyBT/3wnS7u7Xl33/EEfN4B6nQr3Gx5bYxgw==", 754 | "license": "Apache-2.0", 755 | "dependencies": { 756 | "@smithy/node-config-provider": "^3.1.12", 757 | "@smithy/property-provider": "^3.1.11", 758 | "@smithy/types": "^3.7.2", 759 | "@smithy/url-parser": "^3.0.11", 760 | "tslib": "^2.6.2" 761 | }, 762 | "engines": { 763 | "node": ">=16.0.0" 764 | } 765 | }, 766 | "node_modules/@smithy/fetch-http-handler": { 767 | "version": "4.1.2", 768 | "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.2.tgz", 769 | "integrity": "sha512-R7rU7Ae3ItU4rC0c5mB2sP5mJNbCfoDc8I5XlYjIZnquyUwec7fEo78F6DA3SmgJgkU1qTMcZJuGblxZsl10ZA==", 770 | "license": "Apache-2.0", 771 | "dependencies": { 772 | "@smithy/protocol-http": "^4.1.8", 773 | "@smithy/querystring-builder": "^3.0.11", 774 | "@smithy/types": "^3.7.2", 775 | "@smithy/util-base64": "^3.0.0", 776 | "tslib": "^2.6.2" 777 | } 778 | }, 779 | "node_modules/@smithy/hash-node": { 780 | "version": "3.0.11", 781 | "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.11.tgz", 782 | "integrity": "sha512-emP23rwYyZhQBvklqTtwetkQlqbNYirDiEEwXl2v0GYWMnCzxst7ZaRAnWuy28njp5kAH54lvkdG37MblZzaHA==", 783 | "license": "Apache-2.0", 784 | "dependencies": { 785 | "@smithy/types": "^3.7.2", 786 | "@smithy/util-buffer-from": "^3.0.0", 787 | "@smithy/util-utf8": "^3.0.0", 788 | "tslib": "^2.6.2" 789 | }, 790 | "engines": { 791 | "node": ">=16.0.0" 792 | } 793 | }, 794 | "node_modules/@smithy/invalid-dependency": { 795 | "version": "3.0.11", 796 | "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.11.tgz", 797 | "integrity": "sha512-NuQmVPEJjUX6c+UELyVz8kUx8Q539EDeNwbRyu4IIF8MeV7hUtq1FB3SHVyki2u++5XLMFqngeMKk7ccspnNyQ==", 798 | "license": "Apache-2.0", 799 | "dependencies": { 800 | "@smithy/types": "^3.7.2", 801 | "tslib": "^2.6.2" 802 | } 803 | }, 804 | "node_modules/@smithy/is-array-buffer": { 805 | "version": "3.0.0", 806 | "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz", 807 | "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==", 808 | "license": "Apache-2.0", 809 | "dependencies": { 810 | "tslib": "^2.6.2" 811 | }, 812 | "engines": { 813 | "node": ">=16.0.0" 814 | } 815 | }, 816 | "node_modules/@smithy/middleware-content-length": { 817 | "version": "3.0.13", 818 | "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.13.tgz", 819 | "integrity": "sha512-zfMhzojhFpIX3P5ug7jxTjfUcIPcGjcQYzB9t+rv0g1TX7B0QdwONW+ATouaLoD7h7LOw/ZlXfkq4xJ/g2TrIw==", 820 | "license": "Apache-2.0", 821 | "dependencies": { 822 | "@smithy/protocol-http": "^4.1.8", 823 | "@smithy/types": "^3.7.2", 824 | "tslib": "^2.6.2" 825 | }, 826 | "engines": { 827 | "node": ">=16.0.0" 828 | } 829 | }, 830 | "node_modules/@smithy/middleware-endpoint": { 831 | "version": "3.2.5", 832 | "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.5.tgz", 833 | "integrity": "sha512-VhJNs/s/lyx4weiZdXSloBgoLoS8osV0dKIain8nGmx7of3QFKu5BSdEuk1z/U8x9iwes1i+XCiNusEvuK1ijg==", 834 | "license": "Apache-2.0", 835 | "dependencies": { 836 | "@smithy/core": "^2.5.5", 837 | "@smithy/middleware-serde": "^3.0.11", 838 | "@smithy/node-config-provider": "^3.1.12", 839 | "@smithy/shared-ini-file-loader": "^3.1.12", 840 | "@smithy/types": "^3.7.2", 841 | "@smithy/url-parser": "^3.0.11", 842 | "@smithy/util-middleware": "^3.0.11", 843 | "tslib": "^2.6.2" 844 | }, 845 | "engines": { 846 | "node": ">=16.0.0" 847 | } 848 | }, 849 | "node_modules/@smithy/middleware-retry": { 850 | "version": "3.0.30", 851 | "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.30.tgz", 852 | "integrity": "sha512-6323RL2BvAR3VQpTjHpa52kH/iSHyxd/G9ohb2MkBk2Ucu+oMtRXT8yi7KTSIS9nb58aupG6nO0OlXnQOAcvmQ==", 853 | "license": "Apache-2.0", 854 | "dependencies": { 855 | "@smithy/node-config-provider": "^3.1.12", 856 | "@smithy/protocol-http": "^4.1.8", 857 | "@smithy/service-error-classification": "^3.0.11", 858 | "@smithy/smithy-client": "^3.5.0", 859 | "@smithy/types": "^3.7.2", 860 | "@smithy/util-middleware": "^3.0.11", 861 | "@smithy/util-retry": "^3.0.11", 862 | "tslib": "^2.6.2", 863 | "uuid": "^9.0.1" 864 | }, 865 | "engines": { 866 | "node": ">=16.0.0" 867 | } 868 | }, 869 | "node_modules/@smithy/middleware-serde": { 870 | "version": "3.0.11", 871 | "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.11.tgz", 872 | "integrity": "sha512-KzPAeySp/fOoQA82TpnwItvX8BBURecpx6ZMu75EZDkAcnPtO6vf7q4aH5QHs/F1s3/snQaSFbbUMcFFZ086Mw==", 873 | "license": "Apache-2.0", 874 | "dependencies": { 875 | "@smithy/types": "^3.7.2", 876 | "tslib": "^2.6.2" 877 | }, 878 | "engines": { 879 | "node": ">=16.0.0" 880 | } 881 | }, 882 | "node_modules/@smithy/middleware-stack": { 883 | "version": "3.0.11", 884 | "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.11.tgz", 885 | "integrity": "sha512-1HGo9a6/ikgOMrTrWL/WiN9N8GSVYpuRQO5kjstAq4CvV59bjqnh7TbdXGQ4vxLD3xlSjfBjq5t1SOELePsLnA==", 886 | "license": "Apache-2.0", 887 | "dependencies": { 888 | "@smithy/types": "^3.7.2", 889 | "tslib": "^2.6.2" 890 | }, 891 | "engines": { 892 | "node": ">=16.0.0" 893 | } 894 | }, 895 | "node_modules/@smithy/node-config-provider": { 896 | "version": "3.1.12", 897 | "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.12.tgz", 898 | "integrity": "sha512-O9LVEu5J/u/FuNlZs+L7Ikn3lz7VB9hb0GtPT9MQeiBmtK8RSY3ULmsZgXhe6VAlgTw0YO+paQx4p8xdbs43vQ==", 899 | "license": "Apache-2.0", 900 | "dependencies": { 901 | "@smithy/property-provider": "^3.1.11", 902 | "@smithy/shared-ini-file-loader": "^3.1.12", 903 | "@smithy/types": "^3.7.2", 904 | "tslib": "^2.6.2" 905 | }, 906 | "engines": { 907 | "node": ">=16.0.0" 908 | } 909 | }, 910 | "node_modules/@smithy/node-http-handler": { 911 | "version": "3.3.2", 912 | "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.2.tgz", 913 | "integrity": "sha512-t4ng1DAd527vlxvOfKFYEe6/QFBcsj7WpNlWTyjorwXXcKw3XlltBGbyHfSJ24QT84nF+agDha9tNYpzmSRZPA==", 914 | "license": "Apache-2.0", 915 | "dependencies": { 916 | "@smithy/abort-controller": "^3.1.9", 917 | "@smithy/protocol-http": "^4.1.8", 918 | "@smithy/querystring-builder": "^3.0.11", 919 | "@smithy/types": "^3.7.2", 920 | "tslib": "^2.6.2" 921 | }, 922 | "engines": { 923 | "node": ">=16.0.0" 924 | } 925 | }, 926 | "node_modules/@smithy/property-provider": { 927 | "version": "3.1.11", 928 | "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz", 929 | "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==", 930 | "license": "Apache-2.0", 931 | "dependencies": { 932 | "@smithy/types": "^3.7.2", 933 | "tslib": "^2.6.2" 934 | }, 935 | "engines": { 936 | "node": ">=16.0.0" 937 | } 938 | }, 939 | "node_modules/@smithy/protocol-http": { 940 | "version": "4.1.8", 941 | "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz", 942 | "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==", 943 | "license": "Apache-2.0", 944 | "dependencies": { 945 | "@smithy/types": "^3.7.2", 946 | "tslib": "^2.6.2" 947 | }, 948 | "engines": { 949 | "node": ">=16.0.0" 950 | } 951 | }, 952 | "node_modules/@smithy/querystring-builder": { 953 | "version": "3.0.11", 954 | "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.11.tgz", 955 | "integrity": "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg==", 956 | "license": "Apache-2.0", 957 | "dependencies": { 958 | "@smithy/types": "^3.7.2", 959 | "@smithy/util-uri-escape": "^3.0.0", 960 | "tslib": "^2.6.2" 961 | }, 962 | "engines": { 963 | "node": ">=16.0.0" 964 | } 965 | }, 966 | "node_modules/@smithy/querystring-parser": { 967 | "version": "3.0.11", 968 | "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.11.tgz", 969 | "integrity": "sha512-Je3kFvCsFMnso1ilPwA7GtlbPaTixa3WwC+K21kmMZHsBEOZYQaqxcMqeFFoU7/slFjKDIpiiPydvdJm8Q/MCw==", 970 | "license": "Apache-2.0", 971 | "dependencies": { 972 | "@smithy/types": "^3.7.2", 973 | "tslib": "^2.6.2" 974 | }, 975 | "engines": { 976 | "node": ">=16.0.0" 977 | } 978 | }, 979 | "node_modules/@smithy/service-error-classification": { 980 | "version": "3.0.11", 981 | "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.11.tgz", 982 | "integrity": "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog==", 983 | "license": "Apache-2.0", 984 | "dependencies": { 985 | "@smithy/types": "^3.7.2" 986 | }, 987 | "engines": { 988 | "node": ">=16.0.0" 989 | } 990 | }, 991 | "node_modules/@smithy/shared-ini-file-loader": { 992 | "version": "3.1.12", 993 | "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.12.tgz", 994 | "integrity": "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q==", 995 | "license": "Apache-2.0", 996 | "dependencies": { 997 | "@smithy/types": "^3.7.2", 998 | "tslib": "^2.6.2" 999 | }, 1000 | "engines": { 1001 | "node": ">=16.0.0" 1002 | } 1003 | }, 1004 | "node_modules/@smithy/signature-v4": { 1005 | "version": "4.2.4", 1006 | "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.4.tgz", 1007 | "integrity": "sha512-5JWeMQYg81TgU4cG+OexAWdvDTs5JDdbEZx+Qr1iPbvo91QFGzjy0IkXAKaXUHqmKUJgSHK0ZxnCkgZpzkeNTA==", 1008 | "license": "Apache-2.0", 1009 | "dependencies": { 1010 | "@smithy/is-array-buffer": "^3.0.0", 1011 | "@smithy/protocol-http": "^4.1.8", 1012 | "@smithy/types": "^3.7.2", 1013 | "@smithy/util-hex-encoding": "^3.0.0", 1014 | "@smithy/util-middleware": "^3.0.11", 1015 | "@smithy/util-uri-escape": "^3.0.0", 1016 | "@smithy/util-utf8": "^3.0.0", 1017 | "tslib": "^2.6.2" 1018 | }, 1019 | "engines": { 1020 | "node": ">=16.0.0" 1021 | } 1022 | }, 1023 | "node_modules/@smithy/smithy-client": { 1024 | "version": "3.5.0", 1025 | "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.5.0.tgz", 1026 | "integrity": "sha512-Y8FeOa7gbDfCWf7njrkoRATPa5eNLUEjlJS5z5rXatYuGkCb80LbHcu8AQR8qgAZZaNHCLyo2N+pxPsV7l+ivg==", 1027 | "license": "Apache-2.0", 1028 | "dependencies": { 1029 | "@smithy/core": "^2.5.5", 1030 | "@smithy/middleware-endpoint": "^3.2.5", 1031 | "@smithy/middleware-stack": "^3.0.11", 1032 | "@smithy/protocol-http": "^4.1.8", 1033 | "@smithy/types": "^3.7.2", 1034 | "@smithy/util-stream": "^3.3.2", 1035 | "tslib": "^2.6.2" 1036 | }, 1037 | "engines": { 1038 | "node": ">=16.0.0" 1039 | } 1040 | }, 1041 | "node_modules/@smithy/types": { 1042 | "version": "3.7.2", 1043 | "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.2.tgz", 1044 | "integrity": "sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg==", 1045 | "license": "Apache-2.0", 1046 | "dependencies": { 1047 | "tslib": "^2.6.2" 1048 | }, 1049 | "engines": { 1050 | "node": ">=16.0.0" 1051 | } 1052 | }, 1053 | "node_modules/@smithy/url-parser": { 1054 | "version": "3.0.11", 1055 | "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.11.tgz", 1056 | "integrity": "sha512-TmlqXkSk8ZPhfc+SQutjmFr5FjC0av3GZP4B/10caK1SbRwe/v+Wzu/R6xEKxoNqL+8nY18s1byiy6HqPG37Aw==", 1057 | "license": "Apache-2.0", 1058 | "dependencies": { 1059 | "@smithy/querystring-parser": "^3.0.11", 1060 | "@smithy/types": "^3.7.2", 1061 | "tslib": "^2.6.2" 1062 | } 1063 | }, 1064 | "node_modules/@smithy/util-base64": { 1065 | "version": "3.0.0", 1066 | "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz", 1067 | "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==", 1068 | "license": "Apache-2.0", 1069 | "dependencies": { 1070 | "@smithy/util-buffer-from": "^3.0.0", 1071 | "@smithy/util-utf8": "^3.0.0", 1072 | "tslib": "^2.6.2" 1073 | }, 1074 | "engines": { 1075 | "node": ">=16.0.0" 1076 | } 1077 | }, 1078 | "node_modules/@smithy/util-body-length-browser": { 1079 | "version": "3.0.0", 1080 | "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz", 1081 | "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==", 1082 | "license": "Apache-2.0", 1083 | "dependencies": { 1084 | "tslib": "^2.6.2" 1085 | } 1086 | }, 1087 | "node_modules/@smithy/util-body-length-node": { 1088 | "version": "3.0.0", 1089 | "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz", 1090 | "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==", 1091 | "license": "Apache-2.0", 1092 | "dependencies": { 1093 | "tslib": "^2.6.2" 1094 | }, 1095 | "engines": { 1096 | "node": ">=16.0.0" 1097 | } 1098 | }, 1099 | "node_modules/@smithy/util-buffer-from": { 1100 | "version": "3.0.0", 1101 | "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz", 1102 | "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==", 1103 | "license": "Apache-2.0", 1104 | "dependencies": { 1105 | "@smithy/is-array-buffer": "^3.0.0", 1106 | "tslib": "^2.6.2" 1107 | }, 1108 | "engines": { 1109 | "node": ">=16.0.0" 1110 | } 1111 | }, 1112 | "node_modules/@smithy/util-config-provider": { 1113 | "version": "3.0.0", 1114 | "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz", 1115 | "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==", 1116 | "license": "Apache-2.0", 1117 | "dependencies": { 1118 | "tslib": "^2.6.2" 1119 | }, 1120 | "engines": { 1121 | "node": ">=16.0.0" 1122 | } 1123 | }, 1124 | "node_modules/@smithy/util-defaults-mode-browser": { 1125 | "version": "3.0.30", 1126 | "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.30.tgz", 1127 | "integrity": "sha512-nLuGmgfcr0gzm64pqF2UT4SGWVG8UGviAdayDlVzJPNa6Z4lqvpDzdRXmLxtOdEjVlTOEdpZ9dd3ZMMu488mzg==", 1128 | "license": "Apache-2.0", 1129 | "dependencies": { 1130 | "@smithy/property-provider": "^3.1.11", 1131 | "@smithy/smithy-client": "^3.5.0", 1132 | "@smithy/types": "^3.7.2", 1133 | "bowser": "^2.11.0", 1134 | "tslib": "^2.6.2" 1135 | }, 1136 | "engines": { 1137 | "node": ">= 10.0.0" 1138 | } 1139 | }, 1140 | "node_modules/@smithy/util-defaults-mode-node": { 1141 | "version": "3.0.30", 1142 | "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.30.tgz", 1143 | "integrity": "sha512-OD63eWoH68vp75mYcfYyuVH+p7Li/mY4sYOROnauDrtObo1cS4uWfsy/zhOTW8F8ZPxQC1ZXZKVxoxvMGUv2Ow==", 1144 | "license": "Apache-2.0", 1145 | "dependencies": { 1146 | "@smithy/config-resolver": "^3.0.13", 1147 | "@smithy/credential-provider-imds": "^3.2.8", 1148 | "@smithy/node-config-provider": "^3.1.12", 1149 | "@smithy/property-provider": "^3.1.11", 1150 | "@smithy/smithy-client": "^3.5.0", 1151 | "@smithy/types": "^3.7.2", 1152 | "tslib": "^2.6.2" 1153 | }, 1154 | "engines": { 1155 | "node": ">= 10.0.0" 1156 | } 1157 | }, 1158 | "node_modules/@smithy/util-endpoints": { 1159 | "version": "2.1.7", 1160 | "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.7.tgz", 1161 | "integrity": "sha512-tSfcqKcN/Oo2STEYCABVuKgJ76nyyr6skGl9t15hs+YaiU06sgMkN7QYjo0BbVw+KT26zok3IzbdSOksQ4YzVw==", 1162 | "license": "Apache-2.0", 1163 | "dependencies": { 1164 | "@smithy/node-config-provider": "^3.1.12", 1165 | "@smithy/types": "^3.7.2", 1166 | "tslib": "^2.6.2" 1167 | }, 1168 | "engines": { 1169 | "node": ">=16.0.0" 1170 | } 1171 | }, 1172 | "node_modules/@smithy/util-hex-encoding": { 1173 | "version": "3.0.0", 1174 | "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz", 1175 | "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==", 1176 | "license": "Apache-2.0", 1177 | "dependencies": { 1178 | "tslib": "^2.6.2" 1179 | }, 1180 | "engines": { 1181 | "node": ">=16.0.0" 1182 | } 1183 | }, 1184 | "node_modules/@smithy/util-middleware": { 1185 | "version": "3.0.11", 1186 | "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.11.tgz", 1187 | "integrity": "sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow==", 1188 | "license": "Apache-2.0", 1189 | "dependencies": { 1190 | "@smithy/types": "^3.7.2", 1191 | "tslib": "^2.6.2" 1192 | }, 1193 | "engines": { 1194 | "node": ">=16.0.0" 1195 | } 1196 | }, 1197 | "node_modules/@smithy/util-retry": { 1198 | "version": "3.0.11", 1199 | "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz", 1200 | "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==", 1201 | "license": "Apache-2.0", 1202 | "dependencies": { 1203 | "@smithy/service-error-classification": "^3.0.11", 1204 | "@smithy/types": "^3.7.2", 1205 | "tslib": "^2.6.2" 1206 | }, 1207 | "engines": { 1208 | "node": ">=16.0.0" 1209 | } 1210 | }, 1211 | "node_modules/@smithy/util-stream": { 1212 | "version": "3.3.2", 1213 | "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.3.2.tgz", 1214 | "integrity": "sha512-sInAqdiVeisUGYAv/FrXpmJ0b4WTFmciTRqzhb7wVuem9BHvhIG7tpiYHLDWrl2stOokNZpTTGqz3mzB2qFwXg==", 1215 | "license": "Apache-2.0", 1216 | "dependencies": { 1217 | "@smithy/fetch-http-handler": "^4.1.2", 1218 | "@smithy/node-http-handler": "^3.3.2", 1219 | "@smithy/types": "^3.7.2", 1220 | "@smithy/util-base64": "^3.0.0", 1221 | "@smithy/util-buffer-from": "^3.0.0", 1222 | "@smithy/util-hex-encoding": "^3.0.0", 1223 | "@smithy/util-utf8": "^3.0.0", 1224 | "tslib": "^2.6.2" 1225 | }, 1226 | "engines": { 1227 | "node": ">=16.0.0" 1228 | } 1229 | }, 1230 | "node_modules/@smithy/util-uri-escape": { 1231 | "version": "3.0.0", 1232 | "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz", 1233 | "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==", 1234 | "license": "Apache-2.0", 1235 | "dependencies": { 1236 | "tslib": "^2.6.2" 1237 | }, 1238 | "engines": { 1239 | "node": ">=16.0.0" 1240 | } 1241 | }, 1242 | "node_modules/@smithy/util-utf8": { 1243 | "version": "3.0.0", 1244 | "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz", 1245 | "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==", 1246 | "license": "Apache-2.0", 1247 | "dependencies": { 1248 | "@smithy/util-buffer-from": "^3.0.0", 1249 | "tslib": "^2.6.2" 1250 | }, 1251 | "engines": { 1252 | "node": ">=16.0.0" 1253 | } 1254 | }, 1255 | "node_modules/@types/node": { 1256 | "version": "22.10.2", 1257 | "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", 1258 | "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", 1259 | "license": "MIT", 1260 | "dependencies": { 1261 | "undici-types": "~6.20.0" 1262 | } 1263 | }, 1264 | "node_modules/@types/uuid": { 1265 | "version": "9.0.8", 1266 | "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", 1267 | "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", 1268 | "license": "MIT" 1269 | }, 1270 | "node_modules/@types/ws": { 1271 | "version": "8.5.13", 1272 | "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.13.tgz", 1273 | "integrity": "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==", 1274 | "license": "MIT", 1275 | "dependencies": { 1276 | "@types/node": "*" 1277 | } 1278 | }, 1279 | "node_modules/argparse": { 1280 | "version": "2.0.1", 1281 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", 1282 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", 1283 | "license": "Python-2.0" 1284 | }, 1285 | "node_modules/aws-iot-device-sdk": { 1286 | "version": "2.2.15", 1287 | "resolved": "https://registry.npmjs.org/aws-iot-device-sdk/-/aws-iot-device-sdk-2.2.15.tgz", 1288 | "integrity": "sha512-JEnLUx288ttfuwy+ZJA/g9vFG+M3Mucyo1LXypWC8cNV1D8hGvAxeqHygs9TiinvjUazM7gcXwSA+s3E+tbx/g==", 1289 | "license": "Apache-2.0", 1290 | "dependencies": { 1291 | "@httptoolkit/websocket-stream": "^6.0.1", 1292 | "crypto-js": "4.2.0", 1293 | "minimist": "1.2.6", 1294 | "mqtt": "4.2.8" 1295 | }, 1296 | "engines": { 1297 | "node": ">=8.17.0" 1298 | } 1299 | }, 1300 | "node_modules/balanced-match": { 1301 | "version": "1.0.2", 1302 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 1303 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 1304 | "license": "MIT" 1305 | }, 1306 | "node_modules/base64-js": { 1307 | "version": "1.5.1", 1308 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 1309 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 1310 | "funding": [ 1311 | { 1312 | "type": "github", 1313 | "url": "https://github.com/sponsors/feross" 1314 | }, 1315 | { 1316 | "type": "patreon", 1317 | "url": "https://www.patreon.com/feross" 1318 | }, 1319 | { 1320 | "type": "consulting", 1321 | "url": "https://feross.org/support" 1322 | } 1323 | ], 1324 | "license": "MIT" 1325 | }, 1326 | "node_modules/bl": { 1327 | "version": "4.1.0", 1328 | "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", 1329 | "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", 1330 | "license": "MIT", 1331 | "dependencies": { 1332 | "buffer": "^5.5.0", 1333 | "inherits": "^2.0.4", 1334 | "readable-stream": "^3.4.0" 1335 | } 1336 | }, 1337 | "node_modules/bl/node_modules/readable-stream": { 1338 | "version": "3.6.2", 1339 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 1340 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 1341 | "license": "MIT", 1342 | "dependencies": { 1343 | "inherits": "^2.0.3", 1344 | "string_decoder": "^1.1.1", 1345 | "util-deprecate": "^1.0.1" 1346 | }, 1347 | "engines": { 1348 | "node": ">= 6" 1349 | } 1350 | }, 1351 | "node_modules/bowser": { 1352 | "version": "2.11.0", 1353 | "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", 1354 | "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==", 1355 | "license": "MIT" 1356 | }, 1357 | "node_modules/brace-expansion": { 1358 | "version": "1.1.11", 1359 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 1360 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 1361 | "license": "MIT", 1362 | "dependencies": { 1363 | "balanced-match": "^1.0.0", 1364 | "concat-map": "0.0.1" 1365 | } 1366 | }, 1367 | "node_modules/buffer": { 1368 | "version": "5.7.1", 1369 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", 1370 | "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", 1371 | "funding": [ 1372 | { 1373 | "type": "github", 1374 | "url": "https://github.com/sponsors/feross" 1375 | }, 1376 | { 1377 | "type": "patreon", 1378 | "url": "https://www.patreon.com/feross" 1379 | }, 1380 | { 1381 | "type": "consulting", 1382 | "url": "https://feross.org/support" 1383 | } 1384 | ], 1385 | "license": "MIT", 1386 | "dependencies": { 1387 | "base64-js": "^1.3.1", 1388 | "ieee754": "^1.1.13" 1389 | } 1390 | }, 1391 | "node_modules/buffer-from": { 1392 | "version": "1.1.2", 1393 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", 1394 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", 1395 | "license": "MIT" 1396 | }, 1397 | "node_modules/commist": { 1398 | "version": "1.1.0", 1399 | "resolved": "https://registry.npmjs.org/commist/-/commist-1.1.0.tgz", 1400 | "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", 1401 | "license": "MIT", 1402 | "dependencies": { 1403 | "leven": "^2.1.0", 1404 | "minimist": "^1.1.0" 1405 | } 1406 | }, 1407 | "node_modules/concat-map": { 1408 | "version": "0.0.1", 1409 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 1410 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 1411 | "license": "MIT" 1412 | }, 1413 | "node_modules/concat-stream": { 1414 | "version": "2.0.0", 1415 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", 1416 | "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", 1417 | "engines": [ 1418 | "node >= 6.0" 1419 | ], 1420 | "license": "MIT", 1421 | "dependencies": { 1422 | "buffer-from": "^1.0.0", 1423 | "inherits": "^2.0.3", 1424 | "readable-stream": "^3.0.2", 1425 | "typedarray": "^0.0.6" 1426 | } 1427 | }, 1428 | "node_modules/concat-stream/node_modules/readable-stream": { 1429 | "version": "3.6.2", 1430 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 1431 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 1432 | "license": "MIT", 1433 | "dependencies": { 1434 | "inherits": "^2.0.3", 1435 | "string_decoder": "^1.1.1", 1436 | "util-deprecate": "^1.0.1" 1437 | }, 1438 | "engines": { 1439 | "node": ">= 6" 1440 | } 1441 | }, 1442 | "node_modules/core-util-is": { 1443 | "version": "1.0.3", 1444 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", 1445 | "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", 1446 | "license": "MIT" 1447 | }, 1448 | "node_modules/crypto-js": { 1449 | "version": "4.2.0", 1450 | "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", 1451 | "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==", 1452 | "license": "MIT" 1453 | }, 1454 | "node_modules/debug": { 1455 | "version": "4.4.0", 1456 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 1457 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 1458 | "license": "MIT", 1459 | "dependencies": { 1460 | "ms": "^2.1.3" 1461 | }, 1462 | "engines": { 1463 | "node": ">=6.0" 1464 | }, 1465 | "peerDependenciesMeta": { 1466 | "supports-color": { 1467 | "optional": true 1468 | } 1469 | } 1470 | }, 1471 | "node_modules/duplexify": { 1472 | "version": "3.7.1", 1473 | "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", 1474 | "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", 1475 | "license": "MIT", 1476 | "dependencies": { 1477 | "end-of-stream": "^1.0.0", 1478 | "inherits": "^2.0.1", 1479 | "readable-stream": "^2.0.0", 1480 | "stream-shift": "^1.0.0" 1481 | } 1482 | }, 1483 | "node_modules/end-of-stream": { 1484 | "version": "1.4.4", 1485 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 1486 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 1487 | "license": "MIT", 1488 | "dependencies": { 1489 | "once": "^1.4.0" 1490 | } 1491 | }, 1492 | "node_modules/fast-xml-parser": { 1493 | "version": "4.4.1", 1494 | "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", 1495 | "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", 1496 | "funding": [ 1497 | { 1498 | "type": "github", 1499 | "url": "https://github.com/sponsors/NaturalIntelligence" 1500 | }, 1501 | { 1502 | "type": "paypal", 1503 | "url": "https://paypal.me/naturalintelligence" 1504 | } 1505 | ], 1506 | "license": "MIT", 1507 | "dependencies": { 1508 | "strnum": "^1.0.5" 1509 | }, 1510 | "bin": { 1511 | "fxparser": "src/cli/cli.js" 1512 | } 1513 | }, 1514 | "node_modules/fs.realpath": { 1515 | "version": "1.0.0", 1516 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1517 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 1518 | "license": "ISC" 1519 | }, 1520 | "node_modules/glob": { 1521 | "version": "7.2.3", 1522 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 1523 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 1524 | "deprecated": "Glob versions prior to v9 are no longer supported", 1525 | "license": "ISC", 1526 | "dependencies": { 1527 | "fs.realpath": "^1.0.0", 1528 | "inflight": "^1.0.4", 1529 | "inherits": "2", 1530 | "minimatch": "^3.1.1", 1531 | "once": "^1.3.0", 1532 | "path-is-absolute": "^1.0.0" 1533 | }, 1534 | "engines": { 1535 | "node": "*" 1536 | }, 1537 | "funding": { 1538 | "url": "https://github.com/sponsors/isaacs" 1539 | } 1540 | }, 1541 | "node_modules/help-me": { 1542 | "version": "3.0.0", 1543 | "resolved": "https://registry.npmjs.org/help-me/-/help-me-3.0.0.tgz", 1544 | "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", 1545 | "license": "MIT", 1546 | "dependencies": { 1547 | "glob": "^7.1.6", 1548 | "readable-stream": "^3.6.0" 1549 | } 1550 | }, 1551 | "node_modules/help-me/node_modules/readable-stream": { 1552 | "version": "3.6.2", 1553 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 1554 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 1555 | "license": "MIT", 1556 | "dependencies": { 1557 | "inherits": "^2.0.3", 1558 | "string_decoder": "^1.1.1", 1559 | "util-deprecate": "^1.0.1" 1560 | }, 1561 | "engines": { 1562 | "node": ">= 6" 1563 | } 1564 | }, 1565 | "node_modules/ieee754": { 1566 | "version": "1.2.1", 1567 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 1568 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 1569 | "funding": [ 1570 | { 1571 | "type": "github", 1572 | "url": "https://github.com/sponsors/feross" 1573 | }, 1574 | { 1575 | "type": "patreon", 1576 | "url": "https://www.patreon.com/feross" 1577 | }, 1578 | { 1579 | "type": "consulting", 1580 | "url": "https://feross.org/support" 1581 | } 1582 | ], 1583 | "license": "BSD-3-Clause" 1584 | }, 1585 | "node_modules/inflight": { 1586 | "version": "1.0.6", 1587 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1588 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 1589 | "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", 1590 | "license": "ISC", 1591 | "dependencies": { 1592 | "once": "^1.3.0", 1593 | "wrappy": "1" 1594 | } 1595 | }, 1596 | "node_modules/inherits": { 1597 | "version": "2.0.4", 1598 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1599 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1600 | "license": "ISC" 1601 | }, 1602 | "node_modules/isarray": { 1603 | "version": "1.0.0", 1604 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 1605 | "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", 1606 | "license": "MIT" 1607 | }, 1608 | "node_modules/isomorphic-ws": { 1609 | "version": "4.0.1", 1610 | "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz", 1611 | "integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==", 1612 | "license": "MIT", 1613 | "peerDependencies": { 1614 | "ws": "*" 1615 | } 1616 | }, 1617 | "node_modules/leven": { 1618 | "version": "2.1.0", 1619 | "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", 1620 | "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", 1621 | "license": "MIT", 1622 | "engines": { 1623 | "node": ">=0.10.0" 1624 | } 1625 | }, 1626 | "node_modules/minimatch": { 1627 | "version": "3.1.2", 1628 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1629 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1630 | "license": "ISC", 1631 | "dependencies": { 1632 | "brace-expansion": "^1.1.7" 1633 | }, 1634 | "engines": { 1635 | "node": "*" 1636 | } 1637 | }, 1638 | "node_modules/minimist": { 1639 | "version": "1.2.6", 1640 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", 1641 | "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", 1642 | "license": "MIT" 1643 | }, 1644 | "node_modules/mqtt": { 1645 | "version": "4.2.8", 1646 | "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-4.2.8.tgz", 1647 | "integrity": "sha512-DJYjlXODVXtSDecN8jnNzi6ItX3+ufGsEs9OB3YV24HtkRrh7kpx8L5M1LuyF0KzaiGtWr2PzDcMGAY60KGOSA==", 1648 | "license": "MIT", 1649 | "dependencies": { 1650 | "commist": "^1.0.0", 1651 | "concat-stream": "^2.0.0", 1652 | "debug": "^4.1.1", 1653 | "duplexify": "^4.1.1", 1654 | "help-me": "^3.0.0", 1655 | "inherits": "^2.0.3", 1656 | "minimist": "^1.2.5", 1657 | "mqtt-packet": "^6.8.0", 1658 | "pump": "^3.0.0", 1659 | "readable-stream": "^3.6.0", 1660 | "reinterval": "^1.1.0", 1661 | "split2": "^3.1.0", 1662 | "ws": "^7.5.0", 1663 | "xtend": "^4.0.2" 1664 | }, 1665 | "bin": { 1666 | "mqtt": "bin/mqtt.js", 1667 | "mqtt_pub": "bin/pub.js", 1668 | "mqtt_sub": "bin/sub.js" 1669 | }, 1670 | "engines": { 1671 | "node": ">=10.0.0" 1672 | } 1673 | }, 1674 | "node_modules/mqtt-packet": { 1675 | "version": "6.10.0", 1676 | "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-6.10.0.tgz", 1677 | "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", 1678 | "license": "MIT", 1679 | "dependencies": { 1680 | "bl": "^4.0.2", 1681 | "debug": "^4.1.1", 1682 | "process-nextick-args": "^2.0.1" 1683 | } 1684 | }, 1685 | "node_modules/mqtt/node_modules/duplexify": { 1686 | "version": "4.1.3", 1687 | "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz", 1688 | "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==", 1689 | "license": "MIT", 1690 | "dependencies": { 1691 | "end-of-stream": "^1.4.1", 1692 | "inherits": "^2.0.3", 1693 | "readable-stream": "^3.1.1", 1694 | "stream-shift": "^1.0.2" 1695 | } 1696 | }, 1697 | "node_modules/mqtt/node_modules/readable-stream": { 1698 | "version": "3.6.2", 1699 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 1700 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 1701 | "license": "MIT", 1702 | "dependencies": { 1703 | "inherits": "^2.0.3", 1704 | "string_decoder": "^1.1.1", 1705 | "util-deprecate": "^1.0.1" 1706 | }, 1707 | "engines": { 1708 | "node": ">= 6" 1709 | } 1710 | }, 1711 | "node_modules/mqtt/node_modules/ws": { 1712 | "version": "7.5.10", 1713 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", 1714 | "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", 1715 | "license": "MIT", 1716 | "engines": { 1717 | "node": ">=8.3.0" 1718 | }, 1719 | "peerDependencies": { 1720 | "bufferutil": "^4.0.1", 1721 | "utf-8-validate": "^5.0.2" 1722 | }, 1723 | "peerDependenciesMeta": { 1724 | "bufferutil": { 1725 | "optional": true 1726 | }, 1727 | "utf-8-validate": { 1728 | "optional": true 1729 | } 1730 | } 1731 | }, 1732 | "node_modules/ms": { 1733 | "version": "2.1.3", 1734 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1735 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1736 | "license": "MIT" 1737 | }, 1738 | "node_modules/once": { 1739 | "version": "1.4.0", 1740 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1741 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1742 | "license": "ISC", 1743 | "dependencies": { 1744 | "wrappy": "1" 1745 | } 1746 | }, 1747 | "node_modules/path-is-absolute": { 1748 | "version": "1.0.1", 1749 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1750 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1751 | "license": "MIT", 1752 | "engines": { 1753 | "node": ">=0.10.0" 1754 | } 1755 | }, 1756 | "node_modules/process-nextick-args": { 1757 | "version": "2.0.1", 1758 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 1759 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", 1760 | "license": "MIT" 1761 | }, 1762 | "node_modules/pump": { 1763 | "version": "3.0.2", 1764 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", 1765 | "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", 1766 | "license": "MIT", 1767 | "dependencies": { 1768 | "end-of-stream": "^1.1.0", 1769 | "once": "^1.3.1" 1770 | } 1771 | }, 1772 | "node_modules/readable-stream": { 1773 | "version": "2.3.8", 1774 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", 1775 | "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", 1776 | "license": "MIT", 1777 | "dependencies": { 1778 | "core-util-is": "~1.0.0", 1779 | "inherits": "~2.0.3", 1780 | "isarray": "~1.0.0", 1781 | "process-nextick-args": "~2.0.0", 1782 | "safe-buffer": "~5.1.1", 1783 | "string_decoder": "~1.1.1", 1784 | "util-deprecate": "~1.0.1" 1785 | } 1786 | }, 1787 | "node_modules/readable-stream/node_modules/safe-buffer": { 1788 | "version": "5.1.2", 1789 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1790 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 1791 | "license": "MIT" 1792 | }, 1793 | "node_modules/reinterval": { 1794 | "version": "1.1.0", 1795 | "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", 1796 | "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==", 1797 | "license": "MIT" 1798 | }, 1799 | "node_modules/safe-buffer": { 1800 | "version": "5.2.1", 1801 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1802 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1803 | "funding": [ 1804 | { 1805 | "type": "github", 1806 | "url": "https://github.com/sponsors/feross" 1807 | }, 1808 | { 1809 | "type": "patreon", 1810 | "url": "https://www.patreon.com/feross" 1811 | }, 1812 | { 1813 | "type": "consulting", 1814 | "url": "https://feross.org/support" 1815 | } 1816 | ], 1817 | "license": "MIT" 1818 | }, 1819 | "node_modules/split2": { 1820 | "version": "3.2.2", 1821 | "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", 1822 | "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", 1823 | "license": "ISC", 1824 | "dependencies": { 1825 | "readable-stream": "^3.0.0" 1826 | } 1827 | }, 1828 | "node_modules/split2/node_modules/readable-stream": { 1829 | "version": "3.6.2", 1830 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 1831 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 1832 | "license": "MIT", 1833 | "dependencies": { 1834 | "inherits": "^2.0.3", 1835 | "string_decoder": "^1.1.1", 1836 | "util-deprecate": "^1.0.1" 1837 | }, 1838 | "engines": { 1839 | "node": ">= 6" 1840 | } 1841 | }, 1842 | "node_modules/stream-shift": { 1843 | "version": "1.0.3", 1844 | "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz", 1845 | "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==", 1846 | "license": "MIT" 1847 | }, 1848 | "node_modules/string_decoder": { 1849 | "version": "1.1.1", 1850 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 1851 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 1852 | "license": "MIT", 1853 | "dependencies": { 1854 | "safe-buffer": "~5.1.0" 1855 | } 1856 | }, 1857 | "node_modules/string_decoder/node_modules/safe-buffer": { 1858 | "version": "5.1.2", 1859 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1860 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 1861 | "license": "MIT" 1862 | }, 1863 | "node_modules/strnum": { 1864 | "version": "1.0.5", 1865 | "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", 1866 | "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==", 1867 | "license": "MIT" 1868 | }, 1869 | "node_modules/tslib": { 1870 | "version": "2.8.1", 1871 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", 1872 | "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", 1873 | "license": "0BSD" 1874 | }, 1875 | "node_modules/typedarray": { 1876 | "version": "0.0.6", 1877 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 1878 | "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", 1879 | "license": "MIT" 1880 | }, 1881 | "node_modules/undici-types": { 1882 | "version": "6.20.0", 1883 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", 1884 | "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", 1885 | "license": "MIT" 1886 | }, 1887 | "node_modules/util-deprecate": { 1888 | "version": "1.0.2", 1889 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1890 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 1891 | "license": "MIT" 1892 | }, 1893 | "node_modules/uuid": { 1894 | "version": "9.0.1", 1895 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", 1896 | "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", 1897 | "funding": [ 1898 | "https://github.com/sponsors/broofa", 1899 | "https://github.com/sponsors/ctavan" 1900 | ], 1901 | "license": "MIT", 1902 | "bin": { 1903 | "uuid": "dist/bin/uuid" 1904 | } 1905 | }, 1906 | "node_modules/wrappy": { 1907 | "version": "1.0.2", 1908 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1909 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 1910 | "license": "ISC" 1911 | }, 1912 | "node_modules/ws": { 1913 | "version": "8.18.0", 1914 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", 1915 | "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", 1916 | "license": "MIT", 1917 | "engines": { 1918 | "node": ">=10.0.0" 1919 | }, 1920 | "peerDependencies": { 1921 | "bufferutil": "^4.0.1", 1922 | "utf-8-validate": ">=5.0.2" 1923 | }, 1924 | "peerDependenciesMeta": { 1925 | "bufferutil": { 1926 | "optional": true 1927 | }, 1928 | "utf-8-validate": { 1929 | "optional": true 1930 | } 1931 | } 1932 | }, 1933 | "node_modules/xtend": { 1934 | "version": "4.0.2", 1935 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 1936 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", 1937 | "license": "MIT", 1938 | "engines": { 1939 | "node": ">=0.4" 1940 | } 1941 | } 1942 | } 1943 | } 1944 | -------------------------------------------------------------------------------- /sensor/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aws-appsync-iot-core-realtime-sensor", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | }, 9 | "author": "David Moser ", 10 | "license": "MIT-0", 11 | "dependencies": { 12 | "@aws-sdk/client-iot": "^3.708.0", 13 | "argparse": "^2.0.1", 14 | "aws-iot-device-sdk": "^2.2.15" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /sensor/policy.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": "2012-10-17", 3 | "Statement": [ 4 | { 5 | "Effect": "Allow", 6 | "Action": "iot:Connect", 7 | "Resource": "*" 8 | }, 9 | { 10 | "Effect": "Allow", 11 | "Action": "iot:Publish", 12 | "Resource": "*" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /sensor/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "clientId": "aws-iot-mobile-demo-sensor", 3 | "host": "", 4 | "keyPath": "", 5 | "certPath": "", 6 | "caPath": "", 7 | "certificateArn": "" 8 | } --------------------------------------------------------------------------------