The actual Mock Firebolt server, which runs as a NodeJS Express server that:
- Opens a socket and uses this socket to communicate with the Firebolt SDK within an app via the socket transport layer of the SDK.
- Presents a RESTful control plane API which can be used to control the responses and behavior of the server. This API can be used via cURL, Postman, the CLI, the web admin app (also served by this same server), or any/all browser extensions which also use this API.
curl --location --request GET 'http://localhost:3333/api/v1/healthcheck'
{
"status": "OK",
"versionInfo": {
"mockFirebolt": "<mockFireboltServerVersionNumber>",
"sdk"
"core": "<coreSdkVersionNumber>",
}
}
NOTE: You'll see one key under sdk
for each SDK enabled either via the .mf.config.json file or a command-line flag.
curl --location --request GET 'http://localhost:3333/api/v1/meta'
{
"status": "OK",
"meta": {
"core": {
"openrpc": "1.2.4",
"info": {
"title": "Firebolt",
"version": "0.1.1"
},
"methods": [
{ }, ...
],
"components": [
{ }, ...
]
},
}
}
curl --location --request GET 'http://localhost:3333/api/v1/meta?dereferenced=true'
{
"status": "OK",
"meta": {
"openrpc": "1.2.4",
"info": {
"title": "Firebolt",
"version": "0.1.1"
},
"methods": [
{ }, ... /* Will not contain $refs */
]
}
curl --location --request POST 'http://localhost:3333/api/v1/state/global/latency' \
--header 'Content-type: application/json' \
--data-raw '{
"latency": {
"min": 10,
"max": 50
}
}'
{
"status": "OK"
}
curl --location --request POST 'http://localhost:3333/api/v1/state/global/latency' \
--header 'Content-type: application/json' \
--data-raw '{
"latency": {
"device.type": {
"min": 2500,
"max": 3500
}
}
}'
{
"status": "OK"
}
# Use overrides, if present, else use static defaults (from first examples in OpenRPC)
curl --location --request POST 'http://localhost:3333/api/v1/state/global/mode' \
--header 'content-type: application/json' \
--data-raw '{
"mode": "DEFAULT"
}'
# Only use static defaults (from first examples in OpenRPC)
curl --location --request POST 'http://localhost:3333/api/v1/state/global/mode' \
--header 'content-type: application/json' \
--data-raw '{
"mode": "box"
}'
{
"status": "OK"
}
curl --location --request POST 'http://localhost:3333/api/v1/state/method/account.id/result' \
--header 'content-type: application/json' \
--data-raw '{
"result": "ACCOUNT-ONE"
}'
curl --location --request POST 'http://localhost:3333/api/v1/state/method/accessibility.voiceGuidance/result' \
--header 'content-type: application/json' \
--data-raw '{
"result": {
"enabled": true,
"speed": 10
}
}'
{
"status": "OK"
}
{
"status": "ERROR",
"errorCode": "INVALID-STATE-DATA",
"message": "Invalid state data provided",
"error": {
"name": "DataValidationError",
"errors": [
{
"keyword": "required",
"dataPath": "",
"schemaPath": "#/required",
"params": {
"missingProperty": "speed"
},
"message": "should have required property 'speed'"
}
]
}
}
curl --location --request POST 'http://localhost:3333/api/v1/state/method/discovery.watched/error' \
--header 'content-type: application/json' \
--data-raw '{
"error": {
"code": -32999,
"message": "This won'\''t work"
}
}'
{
"status": "OK"
}
curl --location --request PUT 'http://localhost:3333/api/v1/state' \
--header 'content-type: application/json' \
--data-raw '{
"state": {
"global": {
"mode": "DEFAULT"
},
"methods": {
"account.id": {
"result": "A111"
},
"account.uid": {
"result": "A111-222"
},
"discovery.watched": {
"error": {
"code": -32999,
"message": "This won'\''t work"
}
}
}
}
}'
{
"status": "OK"
}
{
"status": "ERROR",
"errorCode": "INVALID-STATE-DATA-1",
"message": "Invalid state data provided",
"error": {
"name": "DataValidationError",
"errors": [
"ERROR: Value type number is not a valid value for account.id: String expected"
]
}
}
curl --location --request GET 'http://localhost:3333/api/v1/state'
{
"status": "OK",
"state": {
"global": {
"mode": "DEFAULT",
"latency": {
"min": 0,
"max": 0
}
},
"scratch": {},
"methods": {
"account.id": {
"result": "A-111"
},
"account.uid": {
"result": "A-111-222"
}
}
}
}
curl --location --request POST 'localhost:3333/api/v1/state/revert'
{
"status": "OK"
}
curl --location --request POST 'http://localhost:3333/api/v1/event' \
--header 'Content-Type: application/json' \
--data-raw '{
"method": "device.onDeviceNameChanged",
"result": "NEW-DEVICE-NAME-1"
}'
{
"status": "OK"
}
curl --location --request POST 'http://localhost:3333/api/v1/broadcastEvent' \
--header 'Content-Type: application/json' \
--data-raw '{
"method": "device.onDeviceNameChanged",
"result": "NEW-DEVICE-NAME-1"
}'
{
"status": "OK"
}
curl --location --request POST 'http://localhost:3333/api/v1/sequence' \
--header 'Content-Type: application/json' \
--data-raw '[{
"at": 5000,
"event": {
"method": "device.onDeviceNameChanged",
"result": "NEW-DEVICE-NAME-1"
}
},
{
"delay": 100,
"event": {
"method": "device.onDeviceNameChanged",
"result": "NEW-DEVICE-NAME-2"
}
},
{
"at": 7000,
"event": {
"method": "device.onDeviceNameChanged",
"result": "NEW-DEVICE-NAME-3"
}
}]'
{
"status": "OK"
}
curl --location --request PUT 'http://localhost:3333/api/v1/user'
curl --location --request POST 'http://localhost:3333/api/v1/user'
{
"status": "OK",
"userId": "<uuid>"
}
curl --location --request PUT 'http://localhost:3333/api/v1/user/123~A'
curl --location --request POST 'http://localhost:3333/api/v1/user/123~A'
{
"status": "OK",
"userId": "123~A"
}
curl --location --request GET 'http://localhost:3333/api/v1/user'
{
"status": "SUCCESS",
"users": [
"<uuid1>",
"<uuid2>",
"<uuid3>",
"<uuid4>"
]
}
curl --location --request GET 'http://localhost:3333/api/v1/status' \
--header 'x-mockfirebolt-userid: sampleUserId1234'
curl --location --request GET 'http://localhost:3333/api/v1/status'
{
status": "WS connection found",
"readyState": "CONNECTED"
}
{
status": "No WS connection found for user 12345"
}
app: {
caseInsensitiveModules: true,
socketPort: 9998,
httpPort: 3333,
wsSessionServerPort: 9999,
conduitSocketPort: 9997,
conduitKeySocketPort: 9996, // Key forwarding from Conduit
developerToolPort: 9995, // Port for Firebolt to connect to
developerToolName: 'Mock Firebolt', // Used when publishing with DNS-SD
defaultUserId: '12345',
magicDateTime: {
prefix: '{{',
suffix: '}}'
},
developerNotesTagName: 'developerNotes'
}
Firebolt calls are passed in the format .. Method names are always formatted with camelCase. However, in early releases of the Firebolt SDK, the module names were fully lowercase. (ex: closedcaptions). Starting with SDK v0.11.0, the module names were altered to begin with an uppercase letter for each word instead (ex: ClosedCaptions). Setting the value for caseInsensitiveModules to true will internally convert the module names passed in method calls to a lowercase string for comparisons. Method names are left in camelCase format. This allows closedcaptions.setEnabled to be treated the same as ClosedCaption.setEnabled in the mock environment.
This can be useful, especially when certifying against different SDK releases.