@hello.nrfcloud.com/nrfcloud-api-helpers 6.0.465 → 6.0.467
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/npm/src/api/DeviceShadow.js +32 -0
- package/npm/src/api/FetchError.js +9 -0
- package/npm/src/api/bulkOps.d.ts +5 -3
- package/npm/src/api/bulkOps.js +22 -0
- package/npm/src/api/cancelFOTAJob.d.ts +1 -1
- package/npm/src/api/cancelFOTAJob.js +15 -0
- package/npm/src/api/createAccountDevice.d.ts +4 -10
- package/npm/src/api/createAccountDevice.js +25 -0
- package/npm/src/api/createFOTAJob.d.ts +4 -3
- package/npm/src/api/createFOTAJob.js +32 -0
- package/npm/src/api/deleteAccountDevice.js +9 -0
- package/npm/src/api/devices.d.ts +47 -27
- package/npm/src/api/devices.js +98 -0
- package/npm/src/api/export.js +18 -0
- package/npm/src/api/getAccountInfo.d.ts +9 -2
- package/npm/src/api/getAccountInfo.js +20 -0
- package/npm/src/api/getCurrentMonthlyCosts.d.ts +1 -1
- package/npm/src/api/getCurrentMonthlyCosts.js +22 -0
- package/npm/src/api/getDeviceShadow.d.ts +21 -18
- package/npm/src/api/getDeviceShadow.js +42 -0
- package/npm/src/api/getFOTABundles.d.ts +11 -3
- package/npm/src/api/getFOTABundles.js +101 -0
- package/npm/src/api/getFOTAJob.d.ts +23 -3
- package/npm/src/api/getFOTAJob.js +114 -0
- package/npm/src/api/getLocationHistory.d.ts +24 -5
- package/npm/src/api/getLocationHistory.js +118 -0
- package/npm/src/api/groundFix.d.ts +8 -4
- package/npm/src/api/groundFix.js +38 -0
- package/npm/src/api/serviceToken.d.ts +2 -2
- package/npm/src/api/serviceToken.js +20 -0
- package/npm/src/api/slashless.js +1 -0
- package/npm/src/api/validatedFetch.d.ts +6 -4
- package/npm/src/api/validatedFetch.js +58 -0
- package/npm/src/settings/export.js +5 -0
- package/npm/src/settings/getAllAccounts.js +9 -0
- package/npm/src/settings/getAllAccountsSettings.js +13 -0
- package/npm/src/settings/groupByAccount.js +16 -0
- package/npm/src/settings/scope.js +6 -0
- package/npm/src/settings/settings.d.ts +7 -13
- package/npm/src/settings/settings.js +83 -0
- package/package.json +3 -3
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Type } from '@sinclair/typebox';
|
|
2
|
+
/**
|
|
3
|
+
* @link https://api.nrfcloud.com/v1/#tag/All-Devices/operation/ListDevices
|
|
4
|
+
*/ export const DeviceShadow = Type.Object({
|
|
5
|
+
id: Type.String(),
|
|
6
|
+
$meta: Type.Object({
|
|
7
|
+
createdAt: Type.String({
|
|
8
|
+
minLength: 1,
|
|
9
|
+
examples: [
|
|
10
|
+
'2019-08-24T14:15:22Z'
|
|
11
|
+
]
|
|
12
|
+
}),
|
|
13
|
+
updatedAt: Type.Optional(Type.String({
|
|
14
|
+
minLength: 1,
|
|
15
|
+
examples: [
|
|
16
|
+
'2019-08-24T14:15:22Z'
|
|
17
|
+
]
|
|
18
|
+
}))
|
|
19
|
+
}),
|
|
20
|
+
state: Type.Optional(Type.Object({
|
|
21
|
+
reported: Type.Optional(Type.Record(Type.String({
|
|
22
|
+
minLength: 1
|
|
23
|
+
}), Type.Any())),
|
|
24
|
+
desired: Type.Optional(Type.Record(Type.String({
|
|
25
|
+
minLength: 1
|
|
26
|
+
}), Type.Any())),
|
|
27
|
+
version: Type.Number(),
|
|
28
|
+
metadata: Type.Record(Type.String({
|
|
29
|
+
minLength: 1
|
|
30
|
+
}), Type.Any())
|
|
31
|
+
}))
|
|
32
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export class FetchError extends Error {
|
|
2
|
+
statusCode;
|
|
3
|
+
constructor(statusCode, message){
|
|
4
|
+
super(message);
|
|
5
|
+
this.statusCode = statusCode;
|
|
6
|
+
this.name = 'FetchError';
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export const toFetchError = async (response)=>new FetchError(response.status, parseInt(response.headers.get('content-length') ?? '0', 10) > 0 ? await response.text() : 'No content returned from server');
|
package/npm/src/api/bulkOps.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type Static } from '@sinclair/typebox';
|
|
2
1
|
import type { FetchError } from './FetchError.ts';
|
|
3
2
|
import { type ValidationError } from './validatedFetch.ts';
|
|
4
3
|
/**
|
|
@@ -11,8 +10,11 @@ export declare const BulkOpsRequestType: import("@sinclair/typebox").TObject<{
|
|
|
11
10
|
export declare const bulkOpsRequests: ({ apiKey, endpoint, }: {
|
|
12
11
|
apiKey: string;
|
|
13
12
|
endpoint: URL;
|
|
14
|
-
}, fetchImplementation?: typeof fetch) => (bulkOpsId: string) => Promise<{
|
|
13
|
+
}, fetchImplementation?: typeof fetch | undefined) => (bulkOpsId: string) => Promise<{
|
|
15
14
|
error: FetchError | ValidationError;
|
|
16
15
|
} | {
|
|
17
|
-
result:
|
|
16
|
+
result: {
|
|
17
|
+
bulkOpsRequestId: string;
|
|
18
|
+
status: "FAILED" | "IN_PROGRESS" | "PENDING" | "SUCCEEDED";
|
|
19
|
+
};
|
|
18
20
|
}>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Type } from '@sinclair/typebox';
|
|
2
|
+
import { validatedFetch } from './validatedFetch.js';
|
|
3
|
+
/**
|
|
4
|
+
* @link https://api.nrfcloud.com/v1/#tag/Bulk-Ops-Requests/operation/FetchBulkOpsRequest
|
|
5
|
+
*/ export const BulkOpsRequestType = Type.Object({
|
|
6
|
+
bulkOpsRequestId: Type.String(),
|
|
7
|
+
status: Type.Union([
|
|
8
|
+
Type.Literal('PENDING'),
|
|
9
|
+
Type.Literal('IN_PROGRESS'),
|
|
10
|
+
Type.Literal('FAILED'),
|
|
11
|
+
Type.Literal('SUCCEEDED')
|
|
12
|
+
])
|
|
13
|
+
});
|
|
14
|
+
export const bulkOpsRequests = ({ apiKey, endpoint }, fetchImplementation)=>async (bulkOpsId)=>{
|
|
15
|
+
const vf = validatedFetch({
|
|
16
|
+
endpoint,
|
|
17
|
+
apiKey
|
|
18
|
+
}, fetchImplementation);
|
|
19
|
+
return vf({
|
|
20
|
+
resource: `bulk-ops-requests/${encodeURIComponent(bulkOpsId)}`
|
|
21
|
+
}, BulkOpsRequestType);
|
|
22
|
+
};
|
|
@@ -3,7 +3,7 @@ import type { ValidationError } from './validatedFetch.ts';
|
|
|
3
3
|
export declare const cancelFOTAJob: ({ apiKey, endpoint, }: {
|
|
4
4
|
apiKey: string;
|
|
5
5
|
endpoint: URL;
|
|
6
|
-
}, fetchImplementation?: typeof fetch) => (jobId: string) => Promise<{
|
|
6
|
+
}, fetchImplementation?: typeof fetch | undefined) => (jobId: string) => Promise<{
|
|
7
7
|
error: FetchError | ValidationError;
|
|
8
8
|
} | {
|
|
9
9
|
success: true;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Type } from '@sinclair/typebox';
|
|
2
|
+
import { validatedFetch } from './validatedFetch.js';
|
|
3
|
+
export const cancelFOTAJob = ({ apiKey, endpoint }, fetchImplementation)=>async (jobId)=>{
|
|
4
|
+
const maybeSuccess = await validatedFetch({
|
|
5
|
+
endpoint,
|
|
6
|
+
apiKey
|
|
7
|
+
}, fetchImplementation)({
|
|
8
|
+
resource: `fota-jobs/${jobId}/cancel`,
|
|
9
|
+
method: 'PUT'
|
|
10
|
+
}, Type.Any());
|
|
11
|
+
if ('error' in maybeSuccess) return maybeSuccess;
|
|
12
|
+
return {
|
|
13
|
+
success: true
|
|
14
|
+
};
|
|
15
|
+
};
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import { type Static } from '@sinclair/typebox';
|
|
2
|
-
/**
|
|
3
|
-
* @link https://api.nrfcloud.com/v1/#tag/Account-Devices/operation/CreateAccountDevice
|
|
4
|
-
*/
|
|
5
|
-
declare const CertificateCredentials: import("@sinclair/typebox").TObject<{
|
|
6
|
-
clientCert: import("@sinclair/typebox").TString;
|
|
7
|
-
privateKey: import("@sinclair/typebox").TString;
|
|
8
|
-
}>;
|
|
9
1
|
export declare const createAccountDevice: ({ apiKey, endpoint, }: {
|
|
10
2
|
apiKey: string;
|
|
11
3
|
endpoint: URL;
|
|
12
|
-
}) => Promise<
|
|
13
|
-
|
|
4
|
+
}) => Promise<{
|
|
5
|
+
clientCert: string;
|
|
6
|
+
privateKey: string;
|
|
7
|
+
}>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Type } from '@sinclair/typebox';
|
|
2
|
+
import { validatedFetch } from './validatedFetch.js';
|
|
3
|
+
/**
|
|
4
|
+
* @link https://api.nrfcloud.com/v1/#tag/Account-Devices/operation/CreateAccountDevice
|
|
5
|
+
*/ const CertificateCredentials = Type.Object({
|
|
6
|
+
clientCert: Type.String(),
|
|
7
|
+
privateKey: Type.String()
|
|
8
|
+
});
|
|
9
|
+
export const createAccountDevice = async ({ apiKey, endpoint })=>{
|
|
10
|
+
const vf = validatedFetch({
|
|
11
|
+
endpoint,
|
|
12
|
+
apiKey
|
|
13
|
+
});
|
|
14
|
+
const maybeResult = await vf({
|
|
15
|
+
resource: 'devices/account',
|
|
16
|
+
method: 'POST'
|
|
17
|
+
}, CertificateCredentials);
|
|
18
|
+
if ('error' in maybeResult) {
|
|
19
|
+
throw maybeResult.error;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
clientCert: maybeResult.result.clientCert,
|
|
23
|
+
privateKey: maybeResult.result.privateKey
|
|
24
|
+
};
|
|
25
|
+
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type Static } from '@sinclair/typebox';
|
|
2
1
|
import type { FetchError } from './FetchError.ts';
|
|
3
2
|
import type { ValidationError } from './validatedFetch.ts';
|
|
4
3
|
export declare const CreateFOTAJobType: import("@sinclair/typebox").TObject<{
|
|
@@ -7,11 +6,13 @@ export declare const CreateFOTAJobType: import("@sinclair/typebox").TObject<{
|
|
|
7
6
|
export declare const createFOTAJob: ({ apiKey, endpoint, }: {
|
|
8
7
|
apiKey: string;
|
|
9
8
|
endpoint: URL;
|
|
10
|
-
}, fetchImplementation?: typeof fetch) => ({ deviceId, bundleId, }: {
|
|
9
|
+
}, fetchImplementation?: typeof fetch | undefined) => ({ deviceId, bundleId, }: {
|
|
11
10
|
deviceId: string;
|
|
12
11
|
bundleId: string;
|
|
13
12
|
}) => Promise<{
|
|
14
13
|
error: FetchError | ValidationError;
|
|
15
14
|
} | {
|
|
16
|
-
result:
|
|
15
|
+
result: {
|
|
16
|
+
jobId: string;
|
|
17
|
+
};
|
|
17
18
|
}>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Type } from '@sinclair/typebox';
|
|
2
|
+
import { JSONPayload, validatedFetch } from './validatedFetch.js';
|
|
3
|
+
export const CreateFOTAJobType = Type.Object({
|
|
4
|
+
jobId: Type.String({
|
|
5
|
+
minLength: 1,
|
|
6
|
+
title: 'ID',
|
|
7
|
+
description: 'Universally unique identifier',
|
|
8
|
+
examples: [
|
|
9
|
+
'bc631093-7f7c-4c1b-aa63-a68c759bcd5c'
|
|
10
|
+
]
|
|
11
|
+
})
|
|
12
|
+
}, {
|
|
13
|
+
title: 'FOTA Job',
|
|
14
|
+
description: 'See https://api.nrfcloud.com/#tag/FOTA-Jobs/operation/CreateFOTAJob'
|
|
15
|
+
});
|
|
16
|
+
export const createFOTAJob = ({ apiKey, endpoint }, fetchImplementation)=>async ({ deviceId, bundleId })=>{
|
|
17
|
+
const maybeJob = await validatedFetch({
|
|
18
|
+
endpoint,
|
|
19
|
+
apiKey
|
|
20
|
+
}, fetchImplementation)({
|
|
21
|
+
resource: 'fota-jobs',
|
|
22
|
+
payload: JSONPayload({
|
|
23
|
+
bundleId,
|
|
24
|
+
autoApply: true,
|
|
25
|
+
deviceIdentifiers: [
|
|
26
|
+
deviceId
|
|
27
|
+
]
|
|
28
|
+
})
|
|
29
|
+
}, CreateFOTAJobType);
|
|
30
|
+
if ('error' in maybeJob) return maybeJob;
|
|
31
|
+
return maybeJob;
|
|
32
|
+
};
|
package/npm/src/api/devices.d.ts
CHANGED
|
@@ -1,23 +1,5 @@
|
|
|
1
|
-
import { type Static } from '@sinclair/typebox';
|
|
2
|
-
import { DeviceShadow } from './DeviceShadow.ts';
|
|
3
1
|
import type { FetchError } from './FetchError.ts';
|
|
4
2
|
import { type ValidationError } from './validatedFetch.ts';
|
|
5
|
-
declare const Devices: import("@sinclair/typebox").TObject<{
|
|
6
|
-
total: import("@sinclair/typebox").TInteger;
|
|
7
|
-
items: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
8
|
-
id: import("@sinclair/typebox").TString;
|
|
9
|
-
$meta: import("@sinclair/typebox").TObject<{
|
|
10
|
-
createdAt: import("@sinclair/typebox").TString;
|
|
11
|
-
updatedAt: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
12
|
-
}>;
|
|
13
|
-
state: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
14
|
-
reported: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TAny>>;
|
|
15
|
-
desired: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TAny>>;
|
|
16
|
-
version: import("@sinclair/typebox").TNumber;
|
|
17
|
-
metadata: import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TAny>;
|
|
18
|
-
}>>;
|
|
19
|
-
}>>;
|
|
20
|
-
}>;
|
|
21
3
|
/**
|
|
22
4
|
* firmware types supported by a device for FOTA
|
|
23
5
|
*/
|
|
@@ -32,20 +14,59 @@ export declare enum FwType {
|
|
|
32
14
|
export declare const devices: ({ endpoint, apiKey, }: {
|
|
33
15
|
endpoint: URL;
|
|
34
16
|
apiKey: string;
|
|
35
|
-
}, fetchImplementation?: typeof fetch) => {
|
|
17
|
+
}, fetchImplementation?: typeof fetch | undefined) => {
|
|
36
18
|
list: () => Promise<{
|
|
37
19
|
error: FetchError | ValidationError;
|
|
38
20
|
} | {
|
|
39
|
-
result:
|
|
21
|
+
result: {
|
|
22
|
+
total: number;
|
|
23
|
+
items: {
|
|
24
|
+
id: string;
|
|
25
|
+
$meta: {
|
|
26
|
+
createdAt: string;
|
|
27
|
+
updatedAt?: string | undefined;
|
|
28
|
+
};
|
|
29
|
+
state?: {
|
|
30
|
+
reported?: {
|
|
31
|
+
[x: string]: any;
|
|
32
|
+
} | undefined;
|
|
33
|
+
desired?: {
|
|
34
|
+
[x: string]: any;
|
|
35
|
+
} | undefined;
|
|
36
|
+
version: number;
|
|
37
|
+
metadata: {
|
|
38
|
+
[x: string]: any;
|
|
39
|
+
};
|
|
40
|
+
} | undefined;
|
|
41
|
+
}[];
|
|
42
|
+
};
|
|
40
43
|
}>;
|
|
41
44
|
get: (id: string) => Promise<{
|
|
42
45
|
error: FetchError | ValidationError;
|
|
43
46
|
} | {
|
|
44
|
-
result:
|
|
47
|
+
result: {
|
|
48
|
+
id: string;
|
|
49
|
+
$meta: {
|
|
50
|
+
createdAt: string;
|
|
51
|
+
updatedAt?: string | undefined;
|
|
52
|
+
};
|
|
53
|
+
state?: {
|
|
54
|
+
reported?: {
|
|
55
|
+
[x: string]: any;
|
|
56
|
+
} | undefined;
|
|
57
|
+
desired?: {
|
|
58
|
+
[x: string]: any;
|
|
59
|
+
} | undefined;
|
|
60
|
+
version: number;
|
|
61
|
+
metadata: {
|
|
62
|
+
[x: string]: any;
|
|
63
|
+
};
|
|
64
|
+
} | undefined;
|
|
65
|
+
};
|
|
45
66
|
}>;
|
|
46
67
|
updateState: (id: string, state: {
|
|
47
|
-
desired?: Record<string, any
|
|
48
|
-
reported?: Record<string, any
|
|
68
|
+
desired?: Record<string, any> | undefined;
|
|
69
|
+
reported?: Record<string, any> | undefined;
|
|
49
70
|
}) => Promise<{
|
|
50
71
|
error: FetchError | ValidationError;
|
|
51
72
|
} | {
|
|
@@ -54,8 +75,8 @@ export declare const devices: ({ endpoint, apiKey, }: {
|
|
|
54
75
|
register: (devices: {
|
|
55
76
|
deviceId: string;
|
|
56
77
|
certPem: string;
|
|
57
|
-
subType?: string;
|
|
58
|
-
tags?: string[];
|
|
78
|
+
subType?: string | undefined;
|
|
79
|
+
tags?: string[] | undefined;
|
|
59
80
|
/**
|
|
60
81
|
* A list of pipe-delimited firmware types that each device supports for FOTA (e.g., APP|MODEM)
|
|
61
82
|
*
|
|
@@ -63,7 +84,7 @@ export declare const devices: ({ endpoint, apiKey, }: {
|
|
|
63
84
|
*
|
|
64
85
|
* @default 'APP|MODEM|BOOT|SOFTDEVICE|BOOTLOADER|MDM_FULL'
|
|
65
86
|
*/
|
|
66
|
-
fwTypes?: FwType[];
|
|
87
|
+
fwTypes?: FwType[] | undefined;
|
|
67
88
|
}[]) => Promise<{
|
|
68
89
|
error: FetchError | ValidationError;
|
|
69
90
|
} | {
|
|
@@ -75,4 +96,3 @@ export declare const devices: ({ endpoint, apiKey, }: {
|
|
|
75
96
|
success: boolean;
|
|
76
97
|
}>;
|
|
77
98
|
};
|
|
78
|
-
export {};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Type } from '@sinclair/typebox';
|
|
2
|
+
import { DeviceShadow } from './DeviceShadow.js';
|
|
3
|
+
import { toFetchError } from './FetchError.js';
|
|
4
|
+
import { slashless } from './slashless.js';
|
|
5
|
+
import { validatedFetch } from './validatedFetch.js';
|
|
6
|
+
const Page = (Item)=>Type.Object({
|
|
7
|
+
total: Type.Integer(),
|
|
8
|
+
items: Type.Array(Item)
|
|
9
|
+
});
|
|
10
|
+
const Devices = Page(DeviceShadow);
|
|
11
|
+
/**
|
|
12
|
+
* @link https://api.nrfcloud.com/v1/#tag/IP-Devices/operation/ProvisionDevices
|
|
13
|
+
*/ const ProvisionDevice = Type.Object({
|
|
14
|
+
bulkOpsRequestId: Type.String()
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* firmware types supported by a device for FOTA
|
|
18
|
+
*/ export var FwType = /*#__PURE__*/ function(FwType) {
|
|
19
|
+
FwType["APP"] = "APP";
|
|
20
|
+
FwType["MODEM"] = "MODEM";
|
|
21
|
+
FwType["BOOT"] = "BOOT";
|
|
22
|
+
FwType["SOFTDEVICE"] = "SOFTDEVICE";
|
|
23
|
+
FwType["BOOTLOADER"] = "BOOTLOADER";
|
|
24
|
+
FwType["MDM_FULL"] = "MDM_FULL";
|
|
25
|
+
return FwType;
|
|
26
|
+
}({});
|
|
27
|
+
export const devices = ({ endpoint, apiKey }, fetchImplementation)=>{
|
|
28
|
+
const headers = {
|
|
29
|
+
Authorization: `Bearer ${apiKey}`,
|
|
30
|
+
Accept: 'application/json; charset=utf-8'
|
|
31
|
+
};
|
|
32
|
+
const vf = validatedFetch({
|
|
33
|
+
endpoint,
|
|
34
|
+
apiKey
|
|
35
|
+
}, fetchImplementation);
|
|
36
|
+
return {
|
|
37
|
+
// FIXME: implement pagination
|
|
38
|
+
list: async ()=>vf({
|
|
39
|
+
resource: `devices?${new URLSearchParams({
|
|
40
|
+
pageLimit: '100',
|
|
41
|
+
deviceNameFuzzy: 'oob-'
|
|
42
|
+
}).toString()}`
|
|
43
|
+
}, Devices),
|
|
44
|
+
get: async (id)=>vf({
|
|
45
|
+
resource: `devices/${encodeURIComponent(id)}`
|
|
46
|
+
}, DeviceShadow),
|
|
47
|
+
updateState: async (id, state)=>fetch(`${slashless(endpoint)}/v1/devices/${encodeURIComponent(id)}/state`, {
|
|
48
|
+
headers: {
|
|
49
|
+
...headers,
|
|
50
|
+
'Content-Type': 'application/json'
|
|
51
|
+
},
|
|
52
|
+
method: 'PATCH',
|
|
53
|
+
body: JSON.stringify(state)
|
|
54
|
+
}).then(async (res)=>{
|
|
55
|
+
if (res.status >= 400) return {
|
|
56
|
+
error: await toFetchError(res)
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
success: true
|
|
60
|
+
};
|
|
61
|
+
}),
|
|
62
|
+
register: async (devices)=>{
|
|
63
|
+
const bulkRegistrationPayload = devices.map(({ deviceId, subType, tags, fwTypes, certPem })=>{
|
|
64
|
+
const deviceFwTypes = fwTypes ?? Object.values(FwType);
|
|
65
|
+
return [
|
|
66
|
+
[
|
|
67
|
+
deviceId,
|
|
68
|
+
subType ?? '',
|
|
69
|
+
(tags ?? []).join('|'),
|
|
70
|
+
deviceFwTypes.join('|'),
|
|
71
|
+
`"${certPem}"`
|
|
72
|
+
]
|
|
73
|
+
];
|
|
74
|
+
}).map((cols)=>cols.join(',')).join('\n');
|
|
75
|
+
const maybeResult = await vf({
|
|
76
|
+
resource: 'devices',
|
|
77
|
+
payload: {
|
|
78
|
+
body: bulkRegistrationPayload,
|
|
79
|
+
type: 'application/octet-stream'
|
|
80
|
+
}
|
|
81
|
+
}, ProvisionDevice);
|
|
82
|
+
if ('error' in maybeResult) return maybeResult;
|
|
83
|
+
return {
|
|
84
|
+
bulkOpsRequestId: maybeResult.result.bulkOpsRequestId
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
remove: async (deviceId)=>{
|
|
88
|
+
const maybeResult = await vf({
|
|
89
|
+
method: 'DELETE',
|
|
90
|
+
resource: `devices/${deviceId}`
|
|
91
|
+
}, Type.Any());
|
|
92
|
+
if ('error' in maybeResult) return maybeResult;
|
|
93
|
+
return {
|
|
94
|
+
success: true
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export * from './bulkOps.js';
|
|
2
|
+
export * from './cancelFOTAJob.js';
|
|
3
|
+
export * from './createAccountDevice.js';
|
|
4
|
+
export * from './createFOTAJob.js';
|
|
5
|
+
export * from './deleteAccountDevice.js';
|
|
6
|
+
export * from './devices.js';
|
|
7
|
+
export * from './DeviceShadow.js';
|
|
8
|
+
export * from './FetchError.js';
|
|
9
|
+
export * from './getAccountInfo.js';
|
|
10
|
+
export * from './getCurrentMonthlyCosts.js';
|
|
11
|
+
export * from './getDeviceShadow.js';
|
|
12
|
+
export * from './getFOTABundles.js';
|
|
13
|
+
export * from './getFOTAJob.js';
|
|
14
|
+
export * from './getLocationHistory.js';
|
|
15
|
+
export * from './groundFix.js';
|
|
16
|
+
export * from './serviceToken.js';
|
|
17
|
+
export * from './slashless.js';
|
|
18
|
+
export * from './validatedFetch.js';
|
|
@@ -13,9 +13,16 @@ export type AccountInfo = Static<typeof AccountInfoType>;
|
|
|
13
13
|
export declare const getAccountInfo: ({ apiKey, endpoint, }: {
|
|
14
14
|
apiKey: string;
|
|
15
15
|
endpoint: URL;
|
|
16
|
-
}, fetchImplementation?: typeof fetch) => Promise<{
|
|
16
|
+
}, fetchImplementation?: typeof fetch | undefined) => Promise<{
|
|
17
17
|
error: FetchError | ValidationError;
|
|
18
18
|
} | {
|
|
19
|
-
result:
|
|
19
|
+
result: {
|
|
20
|
+
mqttEndpoint: string;
|
|
21
|
+
mqttTopicPrefix: string;
|
|
22
|
+
team: {
|
|
23
|
+
tenantId: string;
|
|
24
|
+
name: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
20
27
|
}>;
|
|
21
28
|
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Type } from '@sinclair/typebox';
|
|
2
|
+
import { validatedFetch } from './validatedFetch.js';
|
|
3
|
+
const AccountInfoType = Type.Object({
|
|
4
|
+
mqttEndpoint: Type.String(),
|
|
5
|
+
mqttTopicPrefix: Type.String(),
|
|
6
|
+
team: Type.Object({
|
|
7
|
+
tenantId: Type.String(),
|
|
8
|
+
name: Type.String()
|
|
9
|
+
})
|
|
10
|
+
});
|
|
11
|
+
export const getAccountInfo = async ({ apiKey, endpoint }, fetchImplementation)=>{
|
|
12
|
+
const maybeAccount = await validatedFetch({
|
|
13
|
+
endpoint,
|
|
14
|
+
apiKey
|
|
15
|
+
}, fetchImplementation)({
|
|
16
|
+
resource: 'account'
|
|
17
|
+
}, AccountInfoType);
|
|
18
|
+
if ('error' in maybeAccount) return maybeAccount;
|
|
19
|
+
return maybeAccount;
|
|
20
|
+
};
|
|
@@ -3,7 +3,7 @@ import type { ValidationError } from './validatedFetch.ts';
|
|
|
3
3
|
export declare const getCurrentMonthlyCosts: ({ apiKey, endpoint, }: {
|
|
4
4
|
apiKey: string;
|
|
5
5
|
endpoint: URL;
|
|
6
|
-
}, fetchImplementation?: typeof fetch) => () => Promise<{
|
|
6
|
+
}, fetchImplementation?: typeof fetch | undefined) => () => Promise<{
|
|
7
7
|
error: FetchError | ValidationError;
|
|
8
8
|
} | {
|
|
9
9
|
currentMonthTotalCost: number;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Type } from '@sinclair/typebox';
|
|
2
|
+
import { validatedFetch } from './validatedFetch.js';
|
|
3
|
+
export const getCurrentMonthlyCosts = ({ apiKey, endpoint }, fetchImplementation)=>async ()=>{
|
|
4
|
+
const vf = validatedFetch({
|
|
5
|
+
endpoint,
|
|
6
|
+
apiKey
|
|
7
|
+
}, fetchImplementation);
|
|
8
|
+
const maybeResult = await vf({
|
|
9
|
+
resource: 'account'
|
|
10
|
+
}, Type.Object({
|
|
11
|
+
plan: Type.Object({
|
|
12
|
+
currentMonthTotalCost: Type.Number()
|
|
13
|
+
})
|
|
14
|
+
}));
|
|
15
|
+
if ('error' in maybeResult) {
|
|
16
|
+
return maybeResult;
|
|
17
|
+
}
|
|
18
|
+
const currentMonthTotalCost = maybeResult.result.plan.currentMonthTotalCost;
|
|
19
|
+
return {
|
|
20
|
+
currentMonthTotalCost
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -1,25 +1,28 @@
|
|
|
1
|
-
import { type Static } from '@sinclair/typebox';
|
|
2
1
|
import type { FetchError } from './FetchError.ts';
|
|
3
2
|
import type { ValidationError } from './validatedFetch.ts';
|
|
4
|
-
declare const DeviceShadows: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
5
|
-
id: import("@sinclair/typebox").TString;
|
|
6
|
-
$meta: import("@sinclair/typebox").TObject<{
|
|
7
|
-
createdAt: import("@sinclair/typebox").TString;
|
|
8
|
-
updatedAt: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
9
|
-
}>;
|
|
10
|
-
state: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
|
|
11
|
-
reported: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TAny>>;
|
|
12
|
-
desired: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TAny>>;
|
|
13
|
-
version: import("@sinclair/typebox").TNumber;
|
|
14
|
-
metadata: import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TAny>;
|
|
15
|
-
}>>;
|
|
16
|
-
}>>;
|
|
17
3
|
export declare const getDeviceShadow: ({ endpoint, apiKey, }: {
|
|
18
4
|
endpoint: URL;
|
|
19
5
|
apiKey: string;
|
|
20
|
-
}, fetchImplementation?: typeof fetch) => (
|
|
21
|
-
shadows:
|
|
6
|
+
}, fetchImplementation?: typeof fetch | undefined) => (devices: string[]) => Promise<{
|
|
7
|
+
shadows: {
|
|
8
|
+
id: string;
|
|
9
|
+
$meta: {
|
|
10
|
+
createdAt: string;
|
|
11
|
+
updatedAt?: string | undefined;
|
|
12
|
+
};
|
|
13
|
+
state?: {
|
|
14
|
+
reported?: {
|
|
15
|
+
[x: string]: any;
|
|
16
|
+
} | undefined;
|
|
17
|
+
desired?: {
|
|
18
|
+
[x: string]: any;
|
|
19
|
+
} | undefined;
|
|
20
|
+
version: number;
|
|
21
|
+
metadata: {
|
|
22
|
+
[x: string]: any;
|
|
23
|
+
};
|
|
24
|
+
} | undefined;
|
|
25
|
+
}[];
|
|
22
26
|
} | {
|
|
23
27
|
error: FetchError | ValidationError;
|
|
24
|
-
}
|
|
25
|
-
export {};
|
|
28
|
+
}>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Type } from '@sinclair/typebox';
|
|
2
|
+
import { DeviceShadow } from './DeviceShadow.js';
|
|
3
|
+
import { validatedFetch } from './validatedFetch.js';
|
|
4
|
+
const DeviceShadows = Type.Array(DeviceShadow);
|
|
5
|
+
/**
|
|
6
|
+
* @see https://api.nrfcloud.com/v1#tag/All-Devices/operation/ListDevices
|
|
7
|
+
*/ const ListDevices = Type.Object({
|
|
8
|
+
items: DeviceShadows,
|
|
9
|
+
total: Type.Optional(Type.Number({
|
|
10
|
+
minimum: 0
|
|
11
|
+
})),
|
|
12
|
+
pageNextToken: Type.Optional(Type.String({
|
|
13
|
+
minLength: 1
|
|
14
|
+
}))
|
|
15
|
+
});
|
|
16
|
+
export const getDeviceShadow = ({ endpoint, apiKey }, fetchImplementation)=>{
|
|
17
|
+
const vf = validatedFetch({
|
|
18
|
+
endpoint,
|
|
19
|
+
apiKey
|
|
20
|
+
}, fetchImplementation);
|
|
21
|
+
return async (devices)=>{
|
|
22
|
+
const params = {
|
|
23
|
+
includeState: true,
|
|
24
|
+
includeStateMeta: true,
|
|
25
|
+
pageLimit: 100,
|
|
26
|
+
deviceIds: devices.join(',')
|
|
27
|
+
};
|
|
28
|
+
const queryString = Object.entries(params).sort((a, b)=>a[0].localeCompare(b[0])).map((kv)=>kv.map(encodeURIComponent).join('=')).join('&');
|
|
29
|
+
const url = `devices?${queryString}`;
|
|
30
|
+
const maybeResult = await vf({
|
|
31
|
+
resource: url
|
|
32
|
+
}, ListDevices);
|
|
33
|
+
if ('error' in maybeResult) {
|
|
34
|
+
return {
|
|
35
|
+
error: maybeResult.error
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
shadows: maybeResult.result.items
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type Static } from '@sinclair/typebox';
|
|
2
1
|
import { FwType } from './devices.ts';
|
|
3
2
|
import type { FetchError } from './FetchError.ts';
|
|
4
3
|
import type { ValidationError } from './validatedFetch.ts';
|
|
@@ -15,8 +14,17 @@ export declare const FOTABundle: import("@sinclair/typebox").TObject<{
|
|
|
15
14
|
export declare const getFOTABundles: ({ apiKey, endpoint, }: {
|
|
16
15
|
apiKey: string;
|
|
17
16
|
endpoint: URL;
|
|
18
|
-
}, fetchImplementation?: typeof fetch) => () => Promise<{
|
|
17
|
+
}, fetchImplementation?: typeof fetch | undefined) => () => Promise<{
|
|
19
18
|
error: FetchError | ValidationError;
|
|
20
19
|
} | {
|
|
21
|
-
bundles:
|
|
20
|
+
bundles: {
|
|
21
|
+
bundleId: string;
|
|
22
|
+
lastModified?: string | undefined;
|
|
23
|
+
size: number;
|
|
24
|
+
version: string;
|
|
25
|
+
type: FwType;
|
|
26
|
+
filenames: string[];
|
|
27
|
+
name?: string | undefined;
|
|
28
|
+
description?: string | undefined;
|
|
29
|
+
}[];
|
|
22
30
|
}>;
|