@atlasnpm/atlas-api-helper 0.2.6 → 0.2.7
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/README.md +161 -4
- package/dist/index.cjs +62 -6
- package/dist/index.d.cts +186 -5
- package/dist/index.d.ts +186 -5
- package/dist/index.js +59 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,22 +8,179 @@ npm install @atlasnpm/atlas-api-helper
|
|
|
8
8
|
|
|
9
9
|
## Usage
|
|
10
10
|
|
|
11
|
+
### Using Typed Components (Recommended)
|
|
12
|
+
|
|
13
|
+
The client now supports typed component interfaces that provide IDE autocomplete and type checking:
|
|
14
|
+
|
|
11
15
|
```ts
|
|
12
|
-
import { AtlasHttpClient } from "@atlasnpm/atlas-api-helper";
|
|
16
|
+
import { AtlasHttpClient, EntityComponents, TaskComponents } from "@atlasnpm/atlas-api-helper";
|
|
13
17
|
|
|
14
18
|
const client = new AtlasHttpClient({
|
|
15
19
|
baseUrl: "http://localhost:8000",
|
|
16
20
|
token: "my-api-token",
|
|
17
21
|
});
|
|
18
22
|
|
|
19
|
-
//
|
|
20
|
-
const
|
|
21
|
-
|
|
23
|
+
// Create entity with typed components
|
|
24
|
+
const entityComponents: EntityComponents = {
|
|
25
|
+
telemetry: {
|
|
26
|
+
latitude: 40.7128,
|
|
27
|
+
longitude: -74.0060,
|
|
28
|
+
altitude_m: 120,
|
|
29
|
+
speed_m_s: 8.2,
|
|
30
|
+
heading_deg: 165,
|
|
31
|
+
},
|
|
32
|
+
health: {
|
|
33
|
+
battery_percent: 85,
|
|
34
|
+
},
|
|
35
|
+
communications: {
|
|
36
|
+
link_state: "connected",
|
|
37
|
+
},
|
|
38
|
+
task_catalog: {
|
|
39
|
+
supported_tasks: ["move_to_location", "survey_grid"],
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
await client.createEntity("drone-01", "asset", "Demo Drone", "drone", entityComponents);
|
|
44
|
+
|
|
45
|
+
// Create task with typed components
|
|
46
|
+
const taskComponents: TaskComponents = {
|
|
47
|
+
parameters: {
|
|
48
|
+
latitude: 40.123,
|
|
49
|
+
longitude: -74.456,
|
|
50
|
+
altitude_m: 120,
|
|
51
|
+
},
|
|
52
|
+
progress: {
|
|
53
|
+
percent: 0,
|
|
54
|
+
status_detail: "Pending",
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
await client.createTask("task-1", taskComponents, { entity_id: "drone-01" });
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Using Raw Objects (Legacy)
|
|
62
|
+
|
|
63
|
+
Raw component objects are still supported for backwards compatibility:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import { AtlasHttpClient } from "@atlasnpm/atlas-api-helper";
|
|
67
|
+
|
|
68
|
+
const client = new AtlasHttpClient({
|
|
69
|
+
baseUrl: "http://localhost:8000",
|
|
70
|
+
token: "my-api-token",
|
|
71
|
+
});
|
|
22
72
|
|
|
73
|
+
// Basic entity operations with raw objects
|
|
23
74
|
await client.createEntity("asset-1", "asset", "Surveyor One", "drone", {
|
|
24
75
|
telemetry: { latitude: 40.7, longitude: -74.0 },
|
|
25
76
|
});
|
|
26
77
|
await client.createTask("survey-1", { parameters: { latitude: 40.7, longitude: -74.0 } });
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Typed Component Reference
|
|
81
|
+
|
|
82
|
+
### Entity Components
|
|
83
|
+
|
|
84
|
+
The `EntityComponents` interface accepts the following typed component fields:
|
|
85
|
+
|
|
86
|
+
| Component | Type | Description |
|
|
87
|
+
|-----------|------|-------------|
|
|
88
|
+
| `telemetry` | `TelemetryComponent` | Position and motion data |
|
|
89
|
+
| `geometry` | `GeometryComponent` | GeoJSON geometry for geoentities |
|
|
90
|
+
| `task_catalog` | `TaskCatalogComponent` | Supported task identifiers |
|
|
91
|
+
| `media_refs` | `MediaRefItem[]` | References to media objects |
|
|
92
|
+
| `mil_view` | `MilViewComponent` | Military tactical classification |
|
|
93
|
+
| `health` | `HealthComponent` | Health and vital statistics |
|
|
94
|
+
| `sensor_refs` | `SensorRefItem[]` | Sensor configurations |
|
|
95
|
+
| `communications` | `CommunicationsComponent` | Network link status |
|
|
96
|
+
| `task_queue` | `TaskQueueComponent` | Current and queued work items |
|
|
97
|
+
| `custom_*` | `unknown` | Custom components (must be prefixed with `custom_`) |
|
|
98
|
+
|
|
99
|
+
#### TelemetryComponent
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
const telemetry: TelemetryComponent = {
|
|
103
|
+
latitude: 40.7128, // degrees (WGS84)
|
|
104
|
+
longitude: -74.0060, // degrees (WGS84)
|
|
105
|
+
altitude_m: 120, // meters above sea level
|
|
106
|
+
speed_m_s: 8.2, // horizontal speed in m/s
|
|
107
|
+
heading_deg: 165, // heading (0=N, 90=E)
|
|
108
|
+
};
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### GeometryComponent
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// Point
|
|
115
|
+
const point: GeometryComponent = { type: "Point", coordinates: [-74.0060, 40.7128] };
|
|
116
|
+
|
|
117
|
+
// LineString
|
|
118
|
+
const line: GeometryComponent = { type: "LineString", coordinates: [[-74.0060, 40.7128], [-74.0070, 40.7138]] };
|
|
119
|
+
|
|
120
|
+
// Polygon
|
|
121
|
+
const polygon: GeometryComponent = { type: "Polygon", coordinates: [[[-74.0060, 40.7128], [-74.0070, 40.7128], [-74.0060, 40.7128]]] };
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Task Components
|
|
125
|
+
|
|
126
|
+
The `TaskComponents` interface accepts:
|
|
127
|
+
|
|
128
|
+
| Component | Type | Description |
|
|
129
|
+
|-----------|------|-------------|
|
|
130
|
+
| `parameters` | `TaskParametersComponent` | Command parameters for task execution |
|
|
131
|
+
| `progress` | `TaskProgressComponent` | Runtime telemetry about execution |
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
const taskComponents: TaskComponents = {
|
|
135
|
+
parameters: {
|
|
136
|
+
latitude: 40.123,
|
|
137
|
+
longitude: -74.456,
|
|
138
|
+
altitude_m: 120,
|
|
139
|
+
},
|
|
140
|
+
progress: {
|
|
141
|
+
percent: 65,
|
|
142
|
+
updated_at: "2025-11-25T08:45:00Z",
|
|
143
|
+
status_detail: "En route to destination",
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Custom Components
|
|
149
|
+
|
|
150
|
+
Custom components must be prefixed with `custom_`:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
const components: EntityComponents = {
|
|
154
|
+
telemetry: { latitude: 40.7128 },
|
|
155
|
+
custom_weather: { wind_speed: 12, gusts: 18 }, // Custom component
|
|
156
|
+
};
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Component Validation
|
|
160
|
+
|
|
161
|
+
The client validates component keys before transmission. Unknown component keys that don't start with `custom_` will throw an error:
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
// This will throw an error
|
|
165
|
+
await client.createEntity("test", "asset", "Test", "drone", {
|
|
166
|
+
unknown_component: { foo: "bar" }, // Error: Unknown component 'unknown_component'
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// This works
|
|
170
|
+
await client.createEntity("test", "asset", "Test", "drone", {
|
|
171
|
+
custom_mydata: { foo: "bar" }, // OK: prefixed with custom_
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Complete Example
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
import { AtlasHttpClient } from "@atlasnpm/atlas-api-helper";
|
|
179
|
+
|
|
180
|
+
const client = new AtlasHttpClient({
|
|
181
|
+
baseUrl: "http://localhost:8000",
|
|
182
|
+
token: "my-api-token",
|
|
183
|
+
});
|
|
27
184
|
|
|
28
185
|
// Entity telemetry updates
|
|
29
186
|
const entity = await client.getEntityByAlias("drone-1");
|
package/dist/index.cjs
CHANGED
|
@@ -20,10 +20,58 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
AtlasHttpClient: () => AtlasHttpClient
|
|
23
|
+
AtlasHttpClient: () => AtlasHttpClient,
|
|
24
|
+
componentsToRecord: () => componentsToRecord,
|
|
25
|
+
validateEntityComponents: () => validateEntityComponents
|
|
24
26
|
});
|
|
25
27
|
module.exports = __toCommonJS(index_exports);
|
|
26
28
|
|
|
29
|
+
// src/types/components.ts
|
|
30
|
+
var KNOWN_ENTITY_COMPONENTS = /* @__PURE__ */ new Set([
|
|
31
|
+
"telemetry",
|
|
32
|
+
"geometry",
|
|
33
|
+
"task_catalog",
|
|
34
|
+
"media_refs",
|
|
35
|
+
"mil_view",
|
|
36
|
+
"health",
|
|
37
|
+
"sensor_refs",
|
|
38
|
+
"communications",
|
|
39
|
+
"task_queue"
|
|
40
|
+
]);
|
|
41
|
+
function validateEntityComponents(components) {
|
|
42
|
+
for (const key of Object.keys(components)) {
|
|
43
|
+
if (!KNOWN_ENTITY_COMPONENTS.has(key) && !key.startsWith("custom_")) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
`Unknown component '${key}' in entity components. Custom components must be prefixed with 'custom_'`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function stripNulls(obj) {
|
|
51
|
+
const result = {};
|
|
52
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
53
|
+
if (value === null || value === void 0) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (Array.isArray(value)) {
|
|
57
|
+
result[key] = value.map(
|
|
58
|
+
(item) => typeof item === "object" && item !== null ? stripNulls(item) : item
|
|
59
|
+
);
|
|
60
|
+
} else if (typeof value === "object") {
|
|
61
|
+
result[key] = stripNulls(value);
|
|
62
|
+
} else {
|
|
63
|
+
result[key] = value;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
function componentsToRecord(components) {
|
|
69
|
+
if (components === void 0) {
|
|
70
|
+
return void 0;
|
|
71
|
+
}
|
|
72
|
+
return stripNulls(components);
|
|
73
|
+
}
|
|
74
|
+
|
|
27
75
|
// src/httpClient.ts
|
|
28
76
|
var AtlasHttpClient = class {
|
|
29
77
|
baseUrl;
|
|
@@ -106,7 +154,10 @@ var AtlasHttpClient = class {
|
|
|
106
154
|
alias,
|
|
107
155
|
subtype
|
|
108
156
|
};
|
|
109
|
-
if (components !== void 0)
|
|
157
|
+
if (components !== void 0) {
|
|
158
|
+
validateEntityComponents(components);
|
|
159
|
+
payload.components = componentsToRecord(components);
|
|
160
|
+
}
|
|
110
161
|
return this.request("POST", "/entities", payload);
|
|
111
162
|
}
|
|
112
163
|
updateEntity(entityId, components, options) {
|
|
@@ -114,7 +165,10 @@ var AtlasHttpClient = class {
|
|
|
114
165
|
throw new Error("AtlasHttpClient.updateEntity requires a components payload or subtype.");
|
|
115
166
|
}
|
|
116
167
|
const payload = {};
|
|
117
|
-
if (components !== void 0)
|
|
168
|
+
if (components !== void 0) {
|
|
169
|
+
validateEntityComponents(components);
|
|
170
|
+
payload.components = componentsToRecord(components);
|
|
171
|
+
}
|
|
118
172
|
if (options?.subtype !== void 0) payload.subtype = options.subtype;
|
|
119
173
|
return this.request("PATCH", `/entities/${entityId}`, payload);
|
|
120
174
|
}
|
|
@@ -143,7 +197,7 @@ var AtlasHttpClient = class {
|
|
|
143
197
|
status: options?.status || "pending"
|
|
144
198
|
};
|
|
145
199
|
if (options?.entity_id !== void 0) payload.entity_id = options.entity_id;
|
|
146
|
-
if (components !== void 0) payload.components = components;
|
|
200
|
+
if (components !== void 0) payload.components = componentsToRecord(components);
|
|
147
201
|
if (options?.extra !== void 0) payload.extra = options.extra;
|
|
148
202
|
return this.request("POST", "/tasks", payload);
|
|
149
203
|
}
|
|
@@ -154,7 +208,7 @@ var AtlasHttpClient = class {
|
|
|
154
208
|
);
|
|
155
209
|
}
|
|
156
210
|
const payload = {};
|
|
157
|
-
if (components !== void 0) payload.components = components;
|
|
211
|
+
if (components !== void 0) payload.components = componentsToRecord(components);
|
|
158
212
|
if (options?.status !== void 0) payload.status = options.status;
|
|
159
213
|
if (options?.entity_id !== void 0) payload.entity_id = options.entity_id;
|
|
160
214
|
if (options?.extra !== void 0) payload.extra = options.extra;
|
|
@@ -267,5 +321,7 @@ var AtlasHttpClient = class {
|
|
|
267
321
|
};
|
|
268
322
|
// Annotate the CommonJS export names for ESM import in node:
|
|
269
323
|
0 && (module.exports = {
|
|
270
|
-
AtlasHttpClient
|
|
324
|
+
AtlasHttpClient,
|
|
325
|
+
componentsToRecord,
|
|
326
|
+
validateEntityComponents
|
|
271
327
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed component interfaces for Atlas Command entities, tasks, and objects.
|
|
3
|
+
*
|
|
4
|
+
* These interfaces provide type safety and validation for component data
|
|
5
|
+
* before it is transmitted to the Atlas Command API.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Position and motion data for entities.
|
|
9
|
+
*/
|
|
10
|
+
interface TelemetryComponent {
|
|
11
|
+
/** Latitude in degrees (WGS84) */
|
|
12
|
+
latitude?: number;
|
|
13
|
+
/** Longitude in degrees (WGS84) */
|
|
14
|
+
longitude?: number;
|
|
15
|
+
/** Altitude in meters above sea level */
|
|
16
|
+
altitude_m?: number;
|
|
17
|
+
/** Horizontal speed in meters/second */
|
|
18
|
+
speed_m_s?: number;
|
|
19
|
+
/** Heading in degrees (0=N, 90=E, etc.) */
|
|
20
|
+
heading_deg?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* GeoJSON geometry for geoentities.
|
|
24
|
+
*/
|
|
25
|
+
interface GeometryComponent {
|
|
26
|
+
/** GeoJSON geometry type */
|
|
27
|
+
type: "Point" | "LineString" | "Polygon";
|
|
28
|
+
/** GeoJSON coordinates ([lon, lat] for Point) */
|
|
29
|
+
coordinates: number[] | number[][] | number[][][];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Lists supported task identifiers for an asset.
|
|
33
|
+
*/
|
|
34
|
+
interface TaskCatalogComponent {
|
|
35
|
+
/** Task identifiers the asset can accept */
|
|
36
|
+
supported_tasks: string[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A reference to a media object.
|
|
40
|
+
*/
|
|
41
|
+
interface MediaRefItem {
|
|
42
|
+
/** Object ID in object storage */
|
|
43
|
+
object_id: string;
|
|
44
|
+
/** Role of the media reference */
|
|
45
|
+
role: "camera_feed" | "thumbnail";
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Military tactical classification component.
|
|
49
|
+
*/
|
|
50
|
+
interface MilViewComponent {
|
|
51
|
+
/** Tactical classification */
|
|
52
|
+
classification: "friendly" | "hostile" | "neutral" | "unknown" | "civilian";
|
|
53
|
+
/** ISO 8601 timestamp of last observation */
|
|
54
|
+
last_seen?: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Health and vital statistics for entities.
|
|
58
|
+
*/
|
|
59
|
+
interface HealthComponent {
|
|
60
|
+
/** Battery percentage (0-100) */
|
|
61
|
+
battery_percent?: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A reference to a sensor with FOV/orientation metadata.
|
|
65
|
+
*/
|
|
66
|
+
interface SensorRefItem {
|
|
67
|
+
/** Unique sensor identifier */
|
|
68
|
+
sensor_id: string;
|
|
69
|
+
/** Sensor type (e.g., 'radar') */
|
|
70
|
+
type: string;
|
|
71
|
+
/** Vertical field of view in degrees */
|
|
72
|
+
vertical_fov?: number;
|
|
73
|
+
/** Horizontal field of view in degrees */
|
|
74
|
+
horizontal_fov?: number;
|
|
75
|
+
/** Vertical orientation in degrees relative to level */
|
|
76
|
+
vertical_orientation?: number;
|
|
77
|
+
/** Horizontal orientation in degrees relative to front */
|
|
78
|
+
horizontal_orientation?: number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Network link status component.
|
|
82
|
+
*/
|
|
83
|
+
interface CommunicationsComponent {
|
|
84
|
+
/** Network link state */
|
|
85
|
+
link_state: "connected" | "disconnected" | "degraded" | "unknown";
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Current and queued work items for an entity.
|
|
89
|
+
*/
|
|
90
|
+
interface TaskQueueComponent {
|
|
91
|
+
/** Current task ID (null if idle) */
|
|
92
|
+
current_task_id: string | null;
|
|
93
|
+
/** Ordered list of queued task IDs */
|
|
94
|
+
queued_task_ids: string[];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* All supported entity components with optional fields.
|
|
98
|
+
* Custom components (prefixed with custom_) are allowed via index signature.
|
|
99
|
+
*/
|
|
100
|
+
interface EntityComponents {
|
|
101
|
+
telemetry?: TelemetryComponent;
|
|
102
|
+
geometry?: GeometryComponent;
|
|
103
|
+
task_catalog?: TaskCatalogComponent;
|
|
104
|
+
media_refs?: MediaRefItem[];
|
|
105
|
+
mil_view?: MilViewComponent;
|
|
106
|
+
health?: HealthComponent;
|
|
107
|
+
sensor_refs?: SensorRefItem[];
|
|
108
|
+
communications?: CommunicationsComponent;
|
|
109
|
+
task_queue?: TaskQueueComponent;
|
|
110
|
+
/** Custom components must be prefixed with custom_ */
|
|
111
|
+
[key: `custom_${string}`]: unknown;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Command parameters for task execution.
|
|
115
|
+
*/
|
|
116
|
+
interface TaskParametersComponent {
|
|
117
|
+
latitude?: number;
|
|
118
|
+
longitude?: number;
|
|
119
|
+
altitude_m?: number;
|
|
120
|
+
/** Allow any additional parameters */
|
|
121
|
+
[key: string]: unknown;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Runtime telemetry about task execution.
|
|
125
|
+
*/
|
|
126
|
+
interface TaskProgressComponent {
|
|
127
|
+
/** Progress percentage (0-100) */
|
|
128
|
+
percent?: number;
|
|
129
|
+
/** ISO 8601 timestamp of last update */
|
|
130
|
+
updated_at?: string;
|
|
131
|
+
/** Human-readable status detail */
|
|
132
|
+
status_detail?: string;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* All supported task components.
|
|
136
|
+
*/
|
|
137
|
+
interface TaskComponents {
|
|
138
|
+
parameters?: TaskParametersComponent;
|
|
139
|
+
progress?: TaskProgressComponent;
|
|
140
|
+
/** Allow any additional components */
|
|
141
|
+
[key: string]: unknown;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* A reference from an object to an entity or task.
|
|
145
|
+
*/
|
|
146
|
+
interface ObjectReferenceItem {
|
|
147
|
+
entity_id?: string;
|
|
148
|
+
task_id?: string;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Metadata for stored objects (JSON blob fields).
|
|
152
|
+
*/
|
|
153
|
+
interface ObjectMetadata {
|
|
154
|
+
/** Storage bucket name */
|
|
155
|
+
bucket?: string;
|
|
156
|
+
/** File size in bytes */
|
|
157
|
+
size_bytes?: number;
|
|
158
|
+
/** Hints about object usage */
|
|
159
|
+
usage_hints?: string[];
|
|
160
|
+
/** Entities/tasks that reference this object */
|
|
161
|
+
referenced_by?: ObjectReferenceItem[];
|
|
162
|
+
/** Hash/checksum of object content */
|
|
163
|
+
checksum?: string;
|
|
164
|
+
/** ISO 8601 expiry timestamp */
|
|
165
|
+
expiry_time?: string;
|
|
166
|
+
/** Custom fields */
|
|
167
|
+
[key: `custom_${string}`]: unknown;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Validates that component keys are either known or prefixed with custom_.
|
|
171
|
+
*/
|
|
172
|
+
declare function validateEntityComponents(components: Record<string, unknown>): void;
|
|
173
|
+
/**
|
|
174
|
+
* Convert typed components to a plain object for API transmission.
|
|
175
|
+
* Strips null and undefined values.
|
|
176
|
+
*
|
|
177
|
+
* @param components - Typed component object or raw record
|
|
178
|
+
* @returns Plain object suitable for JSON serialization
|
|
179
|
+
*/
|
|
180
|
+
declare function componentsToRecord(components: EntityComponents | TaskComponents | Record<string, unknown> | undefined): Record<string, unknown> | undefined;
|
|
181
|
+
|
|
1
182
|
interface FetchImplementation {
|
|
2
183
|
(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
|
3
184
|
}
|
|
@@ -19,8 +200,8 @@ declare class AtlasHttpClient {
|
|
|
19
200
|
listEntities(limit?: number, offset?: number): Promise<unknown>;
|
|
20
201
|
getEntity(entityId: string): Promise<unknown>;
|
|
21
202
|
getEntityByAlias(alias: string): Promise<unknown>;
|
|
22
|
-
createEntity(entityId: string, entityType: string, alias: string, subtype: string, components?: JsonRecord): Promise<unknown>;
|
|
23
|
-
updateEntity(entityId: string, components?: JsonRecord, options?: {
|
|
203
|
+
createEntity(entityId: string, entityType: string, alias: string, subtype: string, components?: EntityComponents | JsonRecord): Promise<unknown>;
|
|
204
|
+
updateEntity(entityId: string, components?: EntityComponents | JsonRecord, options?: {
|
|
24
205
|
subtype?: string;
|
|
25
206
|
}): Promise<unknown>;
|
|
26
207
|
deleteEntity(entityId: string): Promise<unknown>;
|
|
@@ -33,12 +214,12 @@ declare class AtlasHttpClient {
|
|
|
33
214
|
}): Promise<unknown>;
|
|
34
215
|
listTasks(limit?: number, status?: string): Promise<unknown>;
|
|
35
216
|
getTask(taskId: string): Promise<unknown>;
|
|
36
|
-
createTask(taskId: string, components?: JsonRecord, options?: {
|
|
217
|
+
createTask(taskId: string, components?: TaskComponents | JsonRecord, options?: {
|
|
37
218
|
status?: string;
|
|
38
219
|
entity_id?: string;
|
|
39
220
|
extra?: JsonRecord;
|
|
40
221
|
}): Promise<unknown>;
|
|
41
|
-
updateTask(taskId: string, components?: JsonRecord, options?: {
|
|
222
|
+
updateTask(taskId: string, components?: TaskComponents | JsonRecord, options?: {
|
|
42
223
|
status?: string;
|
|
43
224
|
entity_id?: string;
|
|
44
225
|
extra?: JsonRecord;
|
|
@@ -217,4 +398,4 @@ interface FullDatasetOptions {
|
|
|
217
398
|
object_limit?: number;
|
|
218
399
|
}
|
|
219
400
|
|
|
220
|
-
export { type Asset, AtlasHttpClient, type ChangedSinceOptions, type ClientOptions, type Command, type CommandDefinition, type Entity, type Event, type EventType, type FetchImplementation, type FullDatasetOptions, type GeoFeature, type JsonRecord, type Model, type ObjectCreate, type ObjectReference, type ObjectUpdate, type Sensor, type StoredObject, type Task, type TaskComplete, type TaskFail, type TaskStart, type TaskStatusUpdate, type Telemetry, type Track, type TrackTelemetry };
|
|
401
|
+
export { type Asset, AtlasHttpClient, type ChangedSinceOptions, type ClientOptions, type Command, type CommandDefinition, type CommunicationsComponent, type Entity, type EntityComponents, type Event, type EventType, type FetchImplementation, type FullDatasetOptions, type GeoFeature, type GeometryComponent, type HealthComponent, type JsonRecord, type MediaRefItem, type MilViewComponent, type Model, type ObjectCreate, type ObjectMetadata, type ObjectReference, type ObjectReferenceItem, type ObjectUpdate, type Sensor, type SensorRefItem, type StoredObject, type Task, type TaskCatalogComponent, type TaskComplete, type TaskComponents, type TaskFail, type TaskParametersComponent, type TaskProgressComponent, type TaskQueueComponent, type TaskStart, type TaskStatusUpdate, type Telemetry, type TelemetryComponent, type Track, type TrackTelemetry, componentsToRecord, validateEntityComponents };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed component interfaces for Atlas Command entities, tasks, and objects.
|
|
3
|
+
*
|
|
4
|
+
* These interfaces provide type safety and validation for component data
|
|
5
|
+
* before it is transmitted to the Atlas Command API.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Position and motion data for entities.
|
|
9
|
+
*/
|
|
10
|
+
interface TelemetryComponent {
|
|
11
|
+
/** Latitude in degrees (WGS84) */
|
|
12
|
+
latitude?: number;
|
|
13
|
+
/** Longitude in degrees (WGS84) */
|
|
14
|
+
longitude?: number;
|
|
15
|
+
/** Altitude in meters above sea level */
|
|
16
|
+
altitude_m?: number;
|
|
17
|
+
/** Horizontal speed in meters/second */
|
|
18
|
+
speed_m_s?: number;
|
|
19
|
+
/** Heading in degrees (0=N, 90=E, etc.) */
|
|
20
|
+
heading_deg?: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* GeoJSON geometry for geoentities.
|
|
24
|
+
*/
|
|
25
|
+
interface GeometryComponent {
|
|
26
|
+
/** GeoJSON geometry type */
|
|
27
|
+
type: "Point" | "LineString" | "Polygon";
|
|
28
|
+
/** GeoJSON coordinates ([lon, lat] for Point) */
|
|
29
|
+
coordinates: number[] | number[][] | number[][][];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Lists supported task identifiers for an asset.
|
|
33
|
+
*/
|
|
34
|
+
interface TaskCatalogComponent {
|
|
35
|
+
/** Task identifiers the asset can accept */
|
|
36
|
+
supported_tasks: string[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A reference to a media object.
|
|
40
|
+
*/
|
|
41
|
+
interface MediaRefItem {
|
|
42
|
+
/** Object ID in object storage */
|
|
43
|
+
object_id: string;
|
|
44
|
+
/** Role of the media reference */
|
|
45
|
+
role: "camera_feed" | "thumbnail";
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Military tactical classification component.
|
|
49
|
+
*/
|
|
50
|
+
interface MilViewComponent {
|
|
51
|
+
/** Tactical classification */
|
|
52
|
+
classification: "friendly" | "hostile" | "neutral" | "unknown" | "civilian";
|
|
53
|
+
/** ISO 8601 timestamp of last observation */
|
|
54
|
+
last_seen?: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Health and vital statistics for entities.
|
|
58
|
+
*/
|
|
59
|
+
interface HealthComponent {
|
|
60
|
+
/** Battery percentage (0-100) */
|
|
61
|
+
battery_percent?: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* A reference to a sensor with FOV/orientation metadata.
|
|
65
|
+
*/
|
|
66
|
+
interface SensorRefItem {
|
|
67
|
+
/** Unique sensor identifier */
|
|
68
|
+
sensor_id: string;
|
|
69
|
+
/** Sensor type (e.g., 'radar') */
|
|
70
|
+
type: string;
|
|
71
|
+
/** Vertical field of view in degrees */
|
|
72
|
+
vertical_fov?: number;
|
|
73
|
+
/** Horizontal field of view in degrees */
|
|
74
|
+
horizontal_fov?: number;
|
|
75
|
+
/** Vertical orientation in degrees relative to level */
|
|
76
|
+
vertical_orientation?: number;
|
|
77
|
+
/** Horizontal orientation in degrees relative to front */
|
|
78
|
+
horizontal_orientation?: number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Network link status component.
|
|
82
|
+
*/
|
|
83
|
+
interface CommunicationsComponent {
|
|
84
|
+
/** Network link state */
|
|
85
|
+
link_state: "connected" | "disconnected" | "degraded" | "unknown";
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Current and queued work items for an entity.
|
|
89
|
+
*/
|
|
90
|
+
interface TaskQueueComponent {
|
|
91
|
+
/** Current task ID (null if idle) */
|
|
92
|
+
current_task_id: string | null;
|
|
93
|
+
/** Ordered list of queued task IDs */
|
|
94
|
+
queued_task_ids: string[];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* All supported entity components with optional fields.
|
|
98
|
+
* Custom components (prefixed with custom_) are allowed via index signature.
|
|
99
|
+
*/
|
|
100
|
+
interface EntityComponents {
|
|
101
|
+
telemetry?: TelemetryComponent;
|
|
102
|
+
geometry?: GeometryComponent;
|
|
103
|
+
task_catalog?: TaskCatalogComponent;
|
|
104
|
+
media_refs?: MediaRefItem[];
|
|
105
|
+
mil_view?: MilViewComponent;
|
|
106
|
+
health?: HealthComponent;
|
|
107
|
+
sensor_refs?: SensorRefItem[];
|
|
108
|
+
communications?: CommunicationsComponent;
|
|
109
|
+
task_queue?: TaskQueueComponent;
|
|
110
|
+
/** Custom components must be prefixed with custom_ */
|
|
111
|
+
[key: `custom_${string}`]: unknown;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Command parameters for task execution.
|
|
115
|
+
*/
|
|
116
|
+
interface TaskParametersComponent {
|
|
117
|
+
latitude?: number;
|
|
118
|
+
longitude?: number;
|
|
119
|
+
altitude_m?: number;
|
|
120
|
+
/** Allow any additional parameters */
|
|
121
|
+
[key: string]: unknown;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Runtime telemetry about task execution.
|
|
125
|
+
*/
|
|
126
|
+
interface TaskProgressComponent {
|
|
127
|
+
/** Progress percentage (0-100) */
|
|
128
|
+
percent?: number;
|
|
129
|
+
/** ISO 8601 timestamp of last update */
|
|
130
|
+
updated_at?: string;
|
|
131
|
+
/** Human-readable status detail */
|
|
132
|
+
status_detail?: string;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* All supported task components.
|
|
136
|
+
*/
|
|
137
|
+
interface TaskComponents {
|
|
138
|
+
parameters?: TaskParametersComponent;
|
|
139
|
+
progress?: TaskProgressComponent;
|
|
140
|
+
/** Allow any additional components */
|
|
141
|
+
[key: string]: unknown;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* A reference from an object to an entity or task.
|
|
145
|
+
*/
|
|
146
|
+
interface ObjectReferenceItem {
|
|
147
|
+
entity_id?: string;
|
|
148
|
+
task_id?: string;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Metadata for stored objects (JSON blob fields).
|
|
152
|
+
*/
|
|
153
|
+
interface ObjectMetadata {
|
|
154
|
+
/** Storage bucket name */
|
|
155
|
+
bucket?: string;
|
|
156
|
+
/** File size in bytes */
|
|
157
|
+
size_bytes?: number;
|
|
158
|
+
/** Hints about object usage */
|
|
159
|
+
usage_hints?: string[];
|
|
160
|
+
/** Entities/tasks that reference this object */
|
|
161
|
+
referenced_by?: ObjectReferenceItem[];
|
|
162
|
+
/** Hash/checksum of object content */
|
|
163
|
+
checksum?: string;
|
|
164
|
+
/** ISO 8601 expiry timestamp */
|
|
165
|
+
expiry_time?: string;
|
|
166
|
+
/** Custom fields */
|
|
167
|
+
[key: `custom_${string}`]: unknown;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Validates that component keys are either known or prefixed with custom_.
|
|
171
|
+
*/
|
|
172
|
+
declare function validateEntityComponents(components: Record<string, unknown>): void;
|
|
173
|
+
/**
|
|
174
|
+
* Convert typed components to a plain object for API transmission.
|
|
175
|
+
* Strips null and undefined values.
|
|
176
|
+
*
|
|
177
|
+
* @param components - Typed component object or raw record
|
|
178
|
+
* @returns Plain object suitable for JSON serialization
|
|
179
|
+
*/
|
|
180
|
+
declare function componentsToRecord(components: EntityComponents | TaskComponents | Record<string, unknown> | undefined): Record<string, unknown> | undefined;
|
|
181
|
+
|
|
1
182
|
interface FetchImplementation {
|
|
2
183
|
(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
|
3
184
|
}
|
|
@@ -19,8 +200,8 @@ declare class AtlasHttpClient {
|
|
|
19
200
|
listEntities(limit?: number, offset?: number): Promise<unknown>;
|
|
20
201
|
getEntity(entityId: string): Promise<unknown>;
|
|
21
202
|
getEntityByAlias(alias: string): Promise<unknown>;
|
|
22
|
-
createEntity(entityId: string, entityType: string, alias: string, subtype: string, components?: JsonRecord): Promise<unknown>;
|
|
23
|
-
updateEntity(entityId: string, components?: JsonRecord, options?: {
|
|
203
|
+
createEntity(entityId: string, entityType: string, alias: string, subtype: string, components?: EntityComponents | JsonRecord): Promise<unknown>;
|
|
204
|
+
updateEntity(entityId: string, components?: EntityComponents | JsonRecord, options?: {
|
|
24
205
|
subtype?: string;
|
|
25
206
|
}): Promise<unknown>;
|
|
26
207
|
deleteEntity(entityId: string): Promise<unknown>;
|
|
@@ -33,12 +214,12 @@ declare class AtlasHttpClient {
|
|
|
33
214
|
}): Promise<unknown>;
|
|
34
215
|
listTasks(limit?: number, status?: string): Promise<unknown>;
|
|
35
216
|
getTask(taskId: string): Promise<unknown>;
|
|
36
|
-
createTask(taskId: string, components?: JsonRecord, options?: {
|
|
217
|
+
createTask(taskId: string, components?: TaskComponents | JsonRecord, options?: {
|
|
37
218
|
status?: string;
|
|
38
219
|
entity_id?: string;
|
|
39
220
|
extra?: JsonRecord;
|
|
40
221
|
}): Promise<unknown>;
|
|
41
|
-
updateTask(taskId: string, components?: JsonRecord, options?: {
|
|
222
|
+
updateTask(taskId: string, components?: TaskComponents | JsonRecord, options?: {
|
|
42
223
|
status?: string;
|
|
43
224
|
entity_id?: string;
|
|
44
225
|
extra?: JsonRecord;
|
|
@@ -217,4 +398,4 @@ interface FullDatasetOptions {
|
|
|
217
398
|
object_limit?: number;
|
|
218
399
|
}
|
|
219
400
|
|
|
220
|
-
export { type Asset, AtlasHttpClient, type ChangedSinceOptions, type ClientOptions, type Command, type CommandDefinition, type Entity, type Event, type EventType, type FetchImplementation, type FullDatasetOptions, type GeoFeature, type JsonRecord, type Model, type ObjectCreate, type ObjectReference, type ObjectUpdate, type Sensor, type StoredObject, type Task, type TaskComplete, type TaskFail, type TaskStart, type TaskStatusUpdate, type Telemetry, type Track, type TrackTelemetry };
|
|
401
|
+
export { type Asset, AtlasHttpClient, type ChangedSinceOptions, type ClientOptions, type Command, type CommandDefinition, type CommunicationsComponent, type Entity, type EntityComponents, type Event, type EventType, type FetchImplementation, type FullDatasetOptions, type GeoFeature, type GeometryComponent, type HealthComponent, type JsonRecord, type MediaRefItem, type MilViewComponent, type Model, type ObjectCreate, type ObjectMetadata, type ObjectReference, type ObjectReferenceItem, type ObjectUpdate, type Sensor, type SensorRefItem, type StoredObject, type Task, type TaskCatalogComponent, type TaskComplete, type TaskComponents, type TaskFail, type TaskParametersComponent, type TaskProgressComponent, type TaskQueueComponent, type TaskStart, type TaskStatusUpdate, type Telemetry, type TelemetryComponent, type Track, type TrackTelemetry, componentsToRecord, validateEntityComponents };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,49 @@
|
|
|
1
|
+
// src/types/components.ts
|
|
2
|
+
var KNOWN_ENTITY_COMPONENTS = /* @__PURE__ */ new Set([
|
|
3
|
+
"telemetry",
|
|
4
|
+
"geometry",
|
|
5
|
+
"task_catalog",
|
|
6
|
+
"media_refs",
|
|
7
|
+
"mil_view",
|
|
8
|
+
"health",
|
|
9
|
+
"sensor_refs",
|
|
10
|
+
"communications",
|
|
11
|
+
"task_queue"
|
|
12
|
+
]);
|
|
13
|
+
function validateEntityComponents(components) {
|
|
14
|
+
for (const key of Object.keys(components)) {
|
|
15
|
+
if (!KNOWN_ENTITY_COMPONENTS.has(key) && !key.startsWith("custom_")) {
|
|
16
|
+
throw new Error(
|
|
17
|
+
`Unknown component '${key}' in entity components. Custom components must be prefixed with 'custom_'`
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function stripNulls(obj) {
|
|
23
|
+
const result = {};
|
|
24
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
25
|
+
if (value === null || value === void 0) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (Array.isArray(value)) {
|
|
29
|
+
result[key] = value.map(
|
|
30
|
+
(item) => typeof item === "object" && item !== null ? stripNulls(item) : item
|
|
31
|
+
);
|
|
32
|
+
} else if (typeof value === "object") {
|
|
33
|
+
result[key] = stripNulls(value);
|
|
34
|
+
} else {
|
|
35
|
+
result[key] = value;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
function componentsToRecord(components) {
|
|
41
|
+
if (components === void 0) {
|
|
42
|
+
return void 0;
|
|
43
|
+
}
|
|
44
|
+
return stripNulls(components);
|
|
45
|
+
}
|
|
46
|
+
|
|
1
47
|
// src/httpClient.ts
|
|
2
48
|
var AtlasHttpClient = class {
|
|
3
49
|
baseUrl;
|
|
@@ -80,7 +126,10 @@ var AtlasHttpClient = class {
|
|
|
80
126
|
alias,
|
|
81
127
|
subtype
|
|
82
128
|
};
|
|
83
|
-
if (components !== void 0)
|
|
129
|
+
if (components !== void 0) {
|
|
130
|
+
validateEntityComponents(components);
|
|
131
|
+
payload.components = componentsToRecord(components);
|
|
132
|
+
}
|
|
84
133
|
return this.request("POST", "/entities", payload);
|
|
85
134
|
}
|
|
86
135
|
updateEntity(entityId, components, options) {
|
|
@@ -88,7 +137,10 @@ var AtlasHttpClient = class {
|
|
|
88
137
|
throw new Error("AtlasHttpClient.updateEntity requires a components payload or subtype.");
|
|
89
138
|
}
|
|
90
139
|
const payload = {};
|
|
91
|
-
if (components !== void 0)
|
|
140
|
+
if (components !== void 0) {
|
|
141
|
+
validateEntityComponents(components);
|
|
142
|
+
payload.components = componentsToRecord(components);
|
|
143
|
+
}
|
|
92
144
|
if (options?.subtype !== void 0) payload.subtype = options.subtype;
|
|
93
145
|
return this.request("PATCH", `/entities/${entityId}`, payload);
|
|
94
146
|
}
|
|
@@ -117,7 +169,7 @@ var AtlasHttpClient = class {
|
|
|
117
169
|
status: options?.status || "pending"
|
|
118
170
|
};
|
|
119
171
|
if (options?.entity_id !== void 0) payload.entity_id = options.entity_id;
|
|
120
|
-
if (components !== void 0) payload.components = components;
|
|
172
|
+
if (components !== void 0) payload.components = componentsToRecord(components);
|
|
121
173
|
if (options?.extra !== void 0) payload.extra = options.extra;
|
|
122
174
|
return this.request("POST", "/tasks", payload);
|
|
123
175
|
}
|
|
@@ -128,7 +180,7 @@ var AtlasHttpClient = class {
|
|
|
128
180
|
);
|
|
129
181
|
}
|
|
130
182
|
const payload = {};
|
|
131
|
-
if (components !== void 0) payload.components = components;
|
|
183
|
+
if (components !== void 0) payload.components = componentsToRecord(components);
|
|
132
184
|
if (options?.status !== void 0) payload.status = options.status;
|
|
133
185
|
if (options?.entity_id !== void 0) payload.entity_id = options.entity_id;
|
|
134
186
|
if (options?.extra !== void 0) payload.extra = options.extra;
|
|
@@ -240,5 +292,7 @@ var AtlasHttpClient = class {
|
|
|
240
292
|
}
|
|
241
293
|
};
|
|
242
294
|
export {
|
|
243
|
-
AtlasHttpClient
|
|
295
|
+
AtlasHttpClient,
|
|
296
|
+
componentsToRecord,
|
|
297
|
+
validateEntityComponents
|
|
244
298
|
};
|