@dronedeploy/rocos-js-sdk 3.0.7 → 3.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  import { AssetStorageService, AuthService, CallerService, CommandService, ConfigGroupService, ControlService, DashboardService, DeviceCredentialsService, EnvironmentService, EvaluatorService, EventService, FileAccessorService, IntegrationService, MapService, ProfileService, ProjectService, RTPWebRTCService, RobotService, SearchService, SpotProvisioningService, SpotProvisioningServiceNode, StreamService, TargetService, TelemetryService, TimeSyncerService, UserService, WebRTCSignallingService, WorkflowService } from './services';
2
2
  import { IBaseService, IDebugLevel, ServiceEnum } from './models';
3
3
  export declare abstract class IRocosSDK {
4
- abstract getService<T extends IBaseService>(name: ServiceEnum): T;
4
+ abstract getService<T extends IBaseService>(_name: ServiceEnum): T;
5
5
  abstract getAuthService(): AuthService;
6
6
  abstract getRobotService(): RobotService;
7
7
  abstract getEventService(): EventService;
package/cjs/RocosSDK.js CHANGED
@@ -338,6 +338,7 @@ class RocosSDK {
338
338
  if (!override)
339
339
  return this.config;
340
340
  // strip out the overrides from the config
341
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
341
342
  const { overrides: _, ...config } = this.config;
342
343
  return {
343
344
  ...config,
@@ -142,6 +142,8 @@ export declare const API_PROJECT_ROBOT_NO_PROFILE_DEPLOYMENTS_URL = "https://{ur
142
142
  export declare const API_PROJECT_PROFILE_DEPLOYED_WORKFLOW_URL = "https://{url}/projects/{projectId}/robot-definitions/{profileId}/automate/flows/deployments/{workflowId}";
143
143
  export declare const API_PROJECT_ROBOT_DEPLOYED_WORKFLOW_URL = "https://{url}/projects/{projectId}/robots/{callsign}/automate/flows/deployments/{workflowId}";
144
144
  export declare const API_PROJECT_WORKFLOW_AFFECTED_URL = "https://{url}/projects/{projectId}/automate/flows/{flowId}/robots";
145
+ export declare const API_PROJECT_WORKFLOW_EXPORT_URL = "https://{url}/projects/{projectId}/automate/flows/{workflowId}/export";
146
+ export declare const API_PROJECT_WORKFLOW_IMPORT_URL = "https://{url}/projects/{projectId}/automate/flows/import";
145
147
  export declare const API_LINKED_PROJECT_URL = "https://{url}/linked-projects/{linkedProjectId}";
146
148
  export declare const API_DEVICE_CREDENTIALS_URL = "https://{url}/projects/{projectId}/callsigns/{callsign}/device-credentials";
147
149
  export declare const API_DEVICE_CREDENTIALS_AUTH_URL = "https://{url}/device-credentials/auth";
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.API_PROJECT_ROBOT_EVENT_HISTORY_URL = exports.API_PROJECT_ROBOT_EVENT_URL = exports.API_PROJECT_ROBOT_REGISTER_URL = exports.API_PROJECT_ROBOT_DEFINITION_URL = exports.API_PROJECT_ROBOT_ATTRIBUTES_URL = exports.API_PROJECT_ROBOT_ID_URL = exports.API_PROJECT_ROBOT_URL = exports.API_PROJECT_MAPPED_ASSET_PATH_URL = exports.API_PROJECT_MAPPED_ASSETS_PATH_URL = exports.API_PROJECT_MISSION_ASSET_PATH_URL = exports.API_PROJECT_MISSION_ASSETS_PATH_URL = exports.API_PROJECT_FLOW_ASSET_PATH_URL = exports.API_PROJECT_ROBOT_ASSET_PATH_URL = exports.API_PROJECT_ASSET_INTEGRATION_PATH_URL = exports.API_PROJECT_ASSET_INTEGRATIONS_PATH_URL = exports.API_PROJECT_ASSET_INTEGRATION_PROVIDERS_PATH_URL = exports.API_PROJECT_ASSET_PROFILES_SYNC_DEFINITION_PATH_URL = exports.API_PROJECT_ASSET_ROBOTS_SYNC_DEFINITION_PATH_URL = exports.API_PROJECT_ASSET_PATH_URL = exports.API_PROJECT_ASSET_URL = exports.API_PROJECT_USERS_URL = exports.API_PROJECT_ID_URL = exports.API_PROJECT_URL = exports.API_ACCOUNT_EXTERNAL_PROJECTS_URL = exports.API_ACCOUNT_PROJECT_APPLICATION_ID_URL = exports.API_ACCOUNT_PROJECT_APPLICATION_URL = exports.API_ACCOUNT_PROJECT_USER_ID_URL = exports.API_ACCOUNT_PROJECT_USER_URL = exports.API_ACCOUNT_PROJECT_ID_URL = exports.API_ACCOUNT_PROJECT_URL = exports.API_SERVER_TIME_URL = exports.API_ACCOUNT_SETTINGS_URL = exports.API_AUTH_USER_ACCOUNT_USER_ID_URL = exports.API_AUTH_USER_ACCOUNT_USER_URL = exports.API_ACCOUNT_ACTIVATE_URL = exports.API_ACCOUNT_ID_URL = exports.API_ACCOUNT_URL = exports.API_USER_PAT_TOKEN_URL = exports.API_USER_PAT_URL = exports.API_USER_VERIFY_EMAIL_URL = exports.API_USER_INVITATION_CHECK_URL = exports.API_USER_INVITATION_ACCEPT_URL = exports.API_USER_INVITATION_URL = exports.API_USER_PASSWORD_FORGOT_URL = exports.API_OTP_AUTH_URL = exports.API_OTP_URL = exports.API_USER_TOKEN_URL = exports.API_USER_URL = exports.API_ADMIN_USER_INVITATION_URL = exports.API_APPLICATION_AUTH_URL = void 0;
4
4
  exports.API_PROJECT_ROBOT_DASHBOARD_ID_URL = exports.API_PROJECT_ROBOT_DASHBOARD_URL = exports.API_PROJECT_STREAM_CALLSIGN_URL = exports.API_PROJECT_STREAM_DATA_URL = exports.API_PROJECT_STREAM_ID_URL = exports.API_PROJECT_STREAM_URL = exports.API_PROJECT_GROUP_TYPE_OWNER_OVERRIDE_URL = exports.API_PROJECT_GROUP_TYPE_OWNER_ID_URL = exports.API_PROJECT_GROUP_TYPE_VERSION_URL = exports.API_PROJECT_GROUP_TYPE_CONFIG_URL = exports.API_PROJECT_GROUP_TYPE_PUBLISH_URL = exports.API_PROJECT_GROUP_TYPE_ID_URL = exports.API_PROJECT_GROUP_TYPE_URL = exports.API_PROJECT_ENVIRONMENT_URL = exports.API_PROJECT_DEFINITION_IMPORT = exports.API_PROJECT_DEFINITION_EXPORT = exports.API_PROJECT_DEFINITION_GAMEPAD_URL = exports.API_PROJECT_DEFINITION_TRIGGER_URL = exports.API_PROJECT_DEFINITION_BUTTON_URL = exports.API_PROJECT_DEFINITION_ACTION_URL = exports.API_PROJECT_DEFINITION_EVENT_URL = exports.API_PROJECT_DEFINITION_COMMAND2_URL = exports.API_PROJECT_DEFINITION_COMMAND_URL = exports.API_PROJECT_DEFINITION_AGENT_URL = exports.API_PROJECT_DEFINITION_SETTING_URL = exports.API_PROJECT_DEFINITION_BLOB_URL = exports.API_PROJECT_DEFINITION_DASHBOARD_URL = exports.API_PROJECT_DEFINITION_COPY_URL = exports.API_PROJECT_DEFINITION_STREAM_URL = exports.API_PROJECT_DEFINITION_ID_URL = exports.API_PROJECT_DEFINITION_URL = exports.API_PROJECT_VROBOT_DEPLOY_URL = exports.API_PROJECT_VROBOT_DETAILS_URL = exports.API_PROJECT_COLLECTION_DOCS_URL = exports.API_PROJECT_COLLECTION_ID_URL = exports.API_PROJECT_DASHBOARD_CUSTOM_WIDGET_URL = exports.API_PROJECT_DASHBOARD_WIDGET_URL = exports.API_PROJECT_DASHBOARD_ID_URL = exports.API_PROJECT_DASHBOARD_URL = exports.API_PROJECT_OPERATION_ID_URL = exports.API_PROJECT_OPERATION_URL = exports.API_PROJECT_ROBOT_CONFIGS_CONNECTION_URL = exports.API_PROJECT_ROBOT_CONFIGS_CONNECTIONS_URL = exports.API_PROJECT_ROBOT_GAMEPAD_URL = exports.API_PROJECT_ROBOT_TRIGGER_URL = exports.API_PROJECT_ROBOT_BUTTON_URL = exports.API_PROJECT_ROBOT_COMMAND2_URL = exports.API_PROJECT_ROBOT_COMMAND_URL = exports.API_PROJECT_ROBOT_AGENT_URL = exports.API_PROJECT_ROBOT_SETTING_URL = void 0;
5
- exports.API_DEVICE_CREDENTIALS_AUTH_URL = exports.API_DEVICE_CREDENTIALS_URL = exports.API_LINKED_PROJECT_URL = exports.API_PROJECT_WORKFLOW_AFFECTED_URL = exports.API_PROJECT_ROBOT_DEPLOYED_WORKFLOW_URL = exports.API_PROJECT_PROFILE_DEPLOYED_WORKFLOW_URL = exports.API_PROJECT_ROBOT_NO_PROFILE_DEPLOYMENTS_URL = exports.API_PROJECT_PROFILE_DEPLOYMENTS_URL = exports.API_PROJECT_ROBOT_DEPLOYMENTS_URL = exports.API_PROJECT_WORKFLOW_ASSET_ID_URL = exports.API_PROJECT_WORKFLOW_ASSET_URL = exports.API_PROJECT_WORKFLOW_ID_URL = exports.API_PROJECT_WORKFLOW_URL = exports.API_GRAPHS_ASSETS_URL = exports.API_GRAPHS_ASSETS_UPLOAD_URL = exports.API_GRAPHS_TARGETS_URL = exports.API_GRAPHS_TARGET_UPLOAD_URL = exports.API_GRAPHS_OBSERVATION_KEYS_URL = exports.API_GRAPHS_OBSERVATIONS_URL = exports.API_GRAPHS_PANORAMA_OBSERVATIONS_URL = exports.API_GRAPHS_PANORAMA = exports.API_GRAPHS_MAPS_GEOJSON_URL = exports.API_GRAPHS_MAPS_DEPLOY_URL = exports.API_GRAPHS_MAPS_COPY_URL = exports.API_GRAPHS_MAP_ID_URL = exports.API_GRAPHS_MAPS_MERGE_URL = exports.API_GRAPHS_MAPS_DEPLOYED_URL = exports.API_GRAPHS_MAPS_URL = exports.API_DD_INTEGRATION_LOCATIONS_URL = exports.API_DD_INTEGRATION_ISSUES_URL = exports.API_DD_INTEGRATION_OVERLAYS_URL = exports.API_DD_INTEGRATION_PLAN_BY_ID_URL = exports.API_DD_INTEGRATION_PLANS_URL = exports.API_SPOTTY_URL = exports.API_PROJECT_SCHEDULES_URL = exports.API_SOURCE_ID_URL = exports.API_SOURCE_URL = exports.API_SOURCE_SCHEMA_URL = exports.API_TEMPLATE_EXPORTER_URL = exports.API_TEMPLATE_PROVISION_ID_URL = exports.API_TEMPLATE_PROVISION_URL = exports.API_TEMPLATE_DEPLOY_URL = exports.API_PROJECT_PROFILE_DASHBOARD_CUSTOM_WIDGET_URL = exports.API_PROJECT_PROFILE_DASHBOARD_ID_URL = exports.API_PROJECT_PROFILE_DASHBOARD_URL = exports.API_PROJECT_CALLSIGN_STREAM_URL = exports.API_PROJECT_ROBOT_DASHBOARD_CUSTOM_WIDGET_URL = void 0;
5
+ exports.API_DEVICE_CREDENTIALS_AUTH_URL = exports.API_DEVICE_CREDENTIALS_URL = exports.API_LINKED_PROJECT_URL = exports.API_PROJECT_WORKFLOW_IMPORT_URL = exports.API_PROJECT_WORKFLOW_EXPORT_URL = exports.API_PROJECT_WORKFLOW_AFFECTED_URL = exports.API_PROJECT_ROBOT_DEPLOYED_WORKFLOW_URL = exports.API_PROJECT_PROFILE_DEPLOYED_WORKFLOW_URL = exports.API_PROJECT_ROBOT_NO_PROFILE_DEPLOYMENTS_URL = exports.API_PROJECT_PROFILE_DEPLOYMENTS_URL = exports.API_PROJECT_ROBOT_DEPLOYMENTS_URL = exports.API_PROJECT_WORKFLOW_ASSET_ID_URL = exports.API_PROJECT_WORKFLOW_ASSET_URL = exports.API_PROJECT_WORKFLOW_ID_URL = exports.API_PROJECT_WORKFLOW_URL = exports.API_GRAPHS_ASSETS_URL = exports.API_GRAPHS_ASSETS_UPLOAD_URL = exports.API_GRAPHS_TARGETS_URL = exports.API_GRAPHS_TARGET_UPLOAD_URL = exports.API_GRAPHS_OBSERVATION_KEYS_URL = exports.API_GRAPHS_OBSERVATIONS_URL = exports.API_GRAPHS_PANORAMA_OBSERVATIONS_URL = exports.API_GRAPHS_PANORAMA = exports.API_GRAPHS_MAPS_GEOJSON_URL = exports.API_GRAPHS_MAPS_DEPLOY_URL = exports.API_GRAPHS_MAPS_COPY_URL = exports.API_GRAPHS_MAP_ID_URL = exports.API_GRAPHS_MAPS_MERGE_URL = exports.API_GRAPHS_MAPS_DEPLOYED_URL = exports.API_GRAPHS_MAPS_URL = exports.API_DD_INTEGRATION_LOCATIONS_URL = exports.API_DD_INTEGRATION_ISSUES_URL = exports.API_DD_INTEGRATION_OVERLAYS_URL = exports.API_DD_INTEGRATION_PLAN_BY_ID_URL = exports.API_DD_INTEGRATION_PLANS_URL = exports.API_SPOTTY_URL = exports.API_PROJECT_SCHEDULES_URL = exports.API_SOURCE_ID_URL = exports.API_SOURCE_URL = exports.API_SOURCE_SCHEMA_URL = exports.API_TEMPLATE_EXPORTER_URL = exports.API_TEMPLATE_PROVISION_ID_URL = exports.API_TEMPLATE_PROVISION_URL = exports.API_TEMPLATE_DEPLOY_URL = exports.API_PROJECT_PROFILE_DASHBOARD_CUSTOM_WIDGET_URL = exports.API_PROJECT_PROFILE_DASHBOARD_ID_URL = exports.API_PROJECT_PROFILE_DASHBOARD_URL = exports.API_PROJECT_CALLSIGN_STREAM_URL = exports.API_PROJECT_ROBOT_DASHBOARD_CUSTOM_WIDGET_URL = void 0;
6
6
  exports.API_APPLICATION_AUTH_URL = 'https://{url}/applications/auth';
7
7
  exports.API_ADMIN_USER_INVITATION_URL = 'https://{url}/admin/users/invitations';
8
8
  exports.API_USER_URL = 'https://{url}/users';
@@ -147,6 +147,8 @@ exports.API_PROJECT_ROBOT_NO_PROFILE_DEPLOYMENTS_URL = 'https://{url}/projects/{
147
147
  exports.API_PROJECT_PROFILE_DEPLOYED_WORKFLOW_URL = 'https://{url}/projects/{projectId}/robot-definitions/{profileId}/automate/flows/deployments/{workflowId}';
148
148
  exports.API_PROJECT_ROBOT_DEPLOYED_WORKFLOW_URL = 'https://{url}/projects/{projectId}/robots/{callsign}/automate/flows/deployments/{workflowId}';
149
149
  exports.API_PROJECT_WORKFLOW_AFFECTED_URL = 'https://{url}/projects/{projectId}/automate/flows/{flowId}/robots';
150
+ exports.API_PROJECT_WORKFLOW_EXPORT_URL = 'https://{url}/projects/{projectId}/automate/flows/{workflowId}/export';
151
+ exports.API_PROJECT_WORKFLOW_IMPORT_URL = 'https://{url}/projects/{projectId}/automate/flows/import';
150
152
  exports.API_LINKED_PROJECT_URL = 'https://{url}/linked-projects/{linkedProjectId}';
151
153
  exports.API_DEVICE_CREDENTIALS_URL = 'https://{url}/projects/{projectId}/callsigns/{callsign}/device-credentials';
152
154
  exports.API_DEVICE_CREDENTIALS_AUTH_URL = 'https://{url}/device-credentials/auth';
@@ -1,16 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.nanosecondToMillisecond = void 0;
4
- function isNumber(n) {
5
- return typeof n === 'number';
6
- }
7
4
  const nanosecondToMillisecond = (nano) => {
8
- if (isNumber(nano)) {
5
+ if (typeof nano === 'number') {
9
6
  return nano / 1e6;
10
7
  }
11
8
  if (nano.length < 16) {
12
9
  return Number(nano) / 1e6;
13
10
  }
14
- return Number(nano.slice(0, -6) + '.' + nano.slice(-6));
11
+ return Number(`${nano.slice(0, -6)}.${nano.slice(-6)}`);
15
12
  };
16
13
  exports.nanosecondToMillisecond = nanosecondToMillisecond;
@@ -1,5 +1,5 @@
1
1
  export interface IRobotSettings {
2
- type: "settings";
2
+ type: 'settings';
3
3
  items: {
4
4
  id: string;
5
5
  value: {
@@ -10,6 +10,11 @@ interface ConfigBase {
10
10
  options?: IStreamOptions;
11
11
  port?: number;
12
12
  insecure?: boolean;
13
+ hooks?: {
14
+ http?: {
15
+ onResponse?: (res: Response) => void;
16
+ };
17
+ };
13
18
  }
14
19
  export interface IRocosSDKConfigApp extends ConfigBase {
15
20
  appId: string;
@@ -61,6 +61,7 @@ class BaseServiceAbstract {
61
61
  async fetchOrThrow(url, config, responseType) {
62
62
  this.logger.debug('Fetching', { url, config });
63
63
  const res = await fetch(url, config);
64
+ this.config.hooks?.http?.onResponse?.(res.clone());
64
65
  if (!res.ok) {
65
66
  const payload = await res.text();
66
67
  this.logger.warn('Failed HTTP Response', { status: res.statusText, payload, response: res });
@@ -83,7 +84,7 @@ class BaseServiceAbstract {
83
84
  try {
84
85
  return JSON.parse(textRes);
85
86
  }
86
- catch (e) {
87
+ catch {
87
88
  this.logger.error('Failed to parse JSON from response', { textRes });
88
89
  return textRes;
89
90
  }
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CallerService = void 0;
4
- const splitRobotTopic_1 = require("../helpers/splitRobotTopic");
5
4
  const models_1 = require("../models");
6
5
  const rxjs_1 = require("rxjs");
7
6
  const operators_1 = require("rxjs/operators");
@@ -9,6 +8,7 @@ const callerMessageHelpers_1 = require("../helpers/callerMessageHelpers");
9
8
  const BaseStreamService_1 = require("./BaseStreamService");
10
9
  const CallerStream_1 = require("../api/streams/caller/CallerStream");
11
10
  const identifier_1 = require("../constants/identifier");
11
+ const splitRobotTopic_1 = require("../helpers/splitRobotTopic");
12
12
  const uuid_1 = require("uuid");
13
13
  class CallerService extends BaseStreamService_1.BaseStreamService {
14
14
  constructor(config) {
@@ -119,9 +119,7 @@ class PlatFormTimeService {
119
119
  let totalServerTimeOffset = 0;
120
120
  const measurementsWithValues = platformTimeMeasurements.filter((x) => !!x?.serverTime);
121
121
  measurementsWithValues.forEach((x) => {
122
- // eslint-disable-next-line operator-linebreak
123
122
  totalServerTimeOffset +=
124
- // eslint-disable-next-line no-mixed-operators
125
123
  x.clientTimeStampEnd - (x.clientTimeStampEnd - x.clientTimeStampStart) / 2 - x.serverTime.now / 10 ** 6;
126
124
  });
127
125
  // final platformTimeOffset is in miliseconds
@@ -126,7 +126,7 @@ class TelemetryService extends BaseStreamService_1.BaseStreamService {
126
126
  sources: [source],
127
127
  callsigns: [callsign],
128
128
  }).pipe((0, rxjs_1.map)(() => Date.now()));
129
- return (0, rxjs_1.combineLatest)([heartbeatTime$.pipe((0, rxjs_1.startWith)(startedAt)), (0, rxjs_1.interval)(intervalMs)]).pipe((0, rxjs_1.map)(([lastHeartbeat, _]) => {
129
+ return (0, rxjs_1.combineLatest)([heartbeatTime$.pipe((0, rxjs_1.startWith)(startedAt)), (0, rxjs_1.interval)(intervalMs)]).pipe((0, rxjs_1.map)(([lastHeartbeat]) => {
130
130
  const now = Date.now();
131
131
  // If we haven't received a heartbeat, but we've only just started
132
132
  if (lastHeartbeat === startedAt && now - startedAt <= heartbeatTimeoutMs) {
@@ -60,20 +60,20 @@ class WebRTCSignallingService {
60
60
  return stream;
61
61
  }
62
62
  async initStream(stream) {
63
+ if (this.config.token)
64
+ return;
63
65
  // an async callback to set the stream token in case one was not set at startup
64
- if (!this.config.token) {
65
- try {
66
- const authService = RocosStore_1.RocosStore.getSDKInstance(this.config).getAuthService();
67
- const token = await authService.getToken();
68
- if (token?.value) {
69
- this.config.token = token?.value;
70
- stream.setToken(this.config.token);
71
- }
72
- }
73
- catch (e) {
74
- this.logger.info('Can not retrieve auth token for web rtc signalling stream', e);
66
+ try {
67
+ const authService = RocosStore_1.RocosStore.getSDKInstance(this.config).getAuthService();
68
+ const token = await authService.getToken();
69
+ if (token?.value) {
70
+ this.config.token = token?.value;
71
+ stream.setToken(this.config.token);
75
72
  }
76
73
  }
74
+ catch (e) {
75
+ this.logger.info('Can not retrieve auth token for web rtc signalling stream', e);
76
+ }
77
77
  }
78
78
  getStream(config) {
79
79
  return new WebRTCSignallingStream_1.WebRTCSignallingStream(config);
@@ -67,4 +67,11 @@ export declare class WorkflowService extends BaseServiceAbstract implements IBas
67
67
  callsigns: string[];
68
68
  profileIds: string[];
69
69
  }>;
70
+ export(projectId: string, workflowId: string): Promise<Blob>;
71
+ import(projectId: string, workflowFile: File | Blob, overrides?: {
72
+ name?: string;
73
+ description?: string;
74
+ id?: string;
75
+ type?: 'cloud' | 'default';
76
+ }): Promise<Workflow>;
70
77
  }
@@ -132,5 +132,21 @@ class WorkflowService extends BaseServiceAbstract_1.BaseServiceAbstract {
132
132
  async getAffectedRobots(projectId, workflowId) {
133
133
  return this.callGet((0, formatServiceUrl_1.formatServiceUrl)(api_1.API_PROJECT_WORKFLOW_AFFECTED_URL, { url: this.config.url, projectId, workflowId, flowId: workflowId }, this.config.insecure), `Failed to get affected robots for ${projectId}, workflowId ${workflowId}.`);
134
134
  }
135
+ async export(projectId, workflowId) {
136
+ return this.callPost((0, formatServiceUrl_1.formatServiceUrl)(api_1.API_PROJECT_WORKFLOW_EXPORT_URL, { url: this.config.url, projectId, workflowId }, this.config.insecure), undefined, `Failed to export workflow for ${projectId}, workflowId ${workflowId}.`, { responseType: 'blob' });
137
+ }
138
+ async import(projectId, workflowFile, overrides) {
139
+ const form = new FormData();
140
+ form.append('file', workflowFile);
141
+ if (overrides?.name)
142
+ form.append('name', overrides.name);
143
+ if (overrides?.description)
144
+ form.append('description', overrides.description);
145
+ if (overrides?.id)
146
+ form.append('id', overrides.id);
147
+ if (overrides?.type)
148
+ form.append('type', overrides.type);
149
+ return this.callPost((0, formatServiceUrl_1.formatServiceUrl)(api_1.API_PROJECT_WORKFLOW_IMPORT_URL, { url: this.config.url, projectId }, this.config.insecure), form, `Failed to import workflow for ${projectId}.`);
150
+ }
135
151
  }
136
152
  exports.WorkflowService = WorkflowService;
@@ -1,7 +1,7 @@
1
1
  import { AssetStorageService, AuthService, CallerService, CommandService, ConfigGroupService, ControlService, DashboardService, DeviceCredentialsService, EnvironmentService, EvaluatorService, EventService, FileAccessorService, IntegrationService, MapService, ProfileService, ProjectService, RTPWebRTCService, RobotService, SearchService, SpotProvisioningService, SpotProvisioningServiceNode, StreamService, TargetService, TelemetryService, TimeSyncerService, UserService, WebRTCSignallingService, WorkflowService } from './services';
2
2
  import { IBaseService, IDebugLevel, ServiceEnum } from './models';
3
3
  export declare abstract class IRocosSDK {
4
- abstract getService<T extends IBaseService>(name: ServiceEnum): T;
4
+ abstract getService<T extends IBaseService>(_name: ServiceEnum): T;
5
5
  abstract getAuthService(): AuthService;
6
6
  abstract getRobotService(): RobotService;
7
7
  abstract getEventService(): EventService;
package/esm/RocosSDK.js CHANGED
@@ -335,6 +335,7 @@ export class RocosSDK {
335
335
  if (!override)
336
336
  return this.config;
337
337
  // strip out the overrides from the config
338
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
338
339
  const { overrides: _, ...config } = this.config;
339
340
  return {
340
341
  ...config,
@@ -142,6 +142,8 @@ export declare const API_PROJECT_ROBOT_NO_PROFILE_DEPLOYMENTS_URL = "https://{ur
142
142
  export declare const API_PROJECT_PROFILE_DEPLOYED_WORKFLOW_URL = "https://{url}/projects/{projectId}/robot-definitions/{profileId}/automate/flows/deployments/{workflowId}";
143
143
  export declare const API_PROJECT_ROBOT_DEPLOYED_WORKFLOW_URL = "https://{url}/projects/{projectId}/robots/{callsign}/automate/flows/deployments/{workflowId}";
144
144
  export declare const API_PROJECT_WORKFLOW_AFFECTED_URL = "https://{url}/projects/{projectId}/automate/flows/{flowId}/robots";
145
+ export declare const API_PROJECT_WORKFLOW_EXPORT_URL = "https://{url}/projects/{projectId}/automate/flows/{workflowId}/export";
146
+ export declare const API_PROJECT_WORKFLOW_IMPORT_URL = "https://{url}/projects/{projectId}/automate/flows/import";
145
147
  export declare const API_LINKED_PROJECT_URL = "https://{url}/linked-projects/{linkedProjectId}";
146
148
  export declare const API_DEVICE_CREDENTIALS_URL = "https://{url}/projects/{projectId}/callsigns/{callsign}/device-credentials";
147
149
  export declare const API_DEVICE_CREDENTIALS_AUTH_URL = "https://{url}/device-credentials/auth";
@@ -142,6 +142,8 @@ export const API_PROJECT_ROBOT_NO_PROFILE_DEPLOYMENTS_URL = 'https://{url}/proje
142
142
  export const API_PROJECT_PROFILE_DEPLOYED_WORKFLOW_URL = 'https://{url}/projects/{projectId}/robot-definitions/{profileId}/automate/flows/deployments/{workflowId}';
143
143
  export const API_PROJECT_ROBOT_DEPLOYED_WORKFLOW_URL = 'https://{url}/projects/{projectId}/robots/{callsign}/automate/flows/deployments/{workflowId}';
144
144
  export const API_PROJECT_WORKFLOW_AFFECTED_URL = 'https://{url}/projects/{projectId}/automate/flows/{flowId}/robots';
145
+ export const API_PROJECT_WORKFLOW_EXPORT_URL = 'https://{url}/projects/{projectId}/automate/flows/{workflowId}/export';
146
+ export const API_PROJECT_WORKFLOW_IMPORT_URL = 'https://{url}/projects/{projectId}/automate/flows/import';
145
147
  export const API_LINKED_PROJECT_URL = 'https://{url}/linked-projects/{linkedProjectId}';
146
148
  export const API_DEVICE_CREDENTIALS_URL = 'https://{url}/projects/{projectId}/callsigns/{callsign}/device-credentials';
147
149
  export const API_DEVICE_CREDENTIALS_AUTH_URL = 'https://{url}/device-credentials/auth';
@@ -1,12 +1,9 @@
1
- function isNumber(n) {
2
- return typeof n === 'number';
3
- }
4
1
  export const nanosecondToMillisecond = (nano) => {
5
- if (isNumber(nano)) {
2
+ if (typeof nano === 'number') {
6
3
  return nano / 1e6;
7
4
  }
8
5
  if (nano.length < 16) {
9
6
  return Number(nano) / 1e6;
10
7
  }
11
- return Number(nano.slice(0, -6) + '.' + nano.slice(-6));
8
+ return Number(`${nano.slice(0, -6)}.${nano.slice(-6)}`);
12
9
  };
@@ -1,5 +1,5 @@
1
1
  export interface IRobotSettings {
2
- type: "settings";
2
+ type: 'settings';
3
3
  items: {
4
4
  id: string;
5
5
  value: {
@@ -10,6 +10,11 @@ interface ConfigBase {
10
10
  options?: IStreamOptions;
11
11
  port?: number;
12
12
  insecure?: boolean;
13
+ hooks?: {
14
+ http?: {
15
+ onResponse?: (res: Response) => void;
16
+ };
17
+ };
13
18
  }
14
19
  export interface IRocosSDKConfigApp extends ConfigBase {
15
20
  appId: string;
@@ -58,6 +58,7 @@ export class BaseServiceAbstract {
58
58
  async fetchOrThrow(url, config, responseType) {
59
59
  this.logger.debug('Fetching', { url, config });
60
60
  const res = await fetch(url, config);
61
+ this.config.hooks?.http?.onResponse?.(res.clone());
61
62
  if (!res.ok) {
62
63
  const payload = await res.text();
63
64
  this.logger.warn('Failed HTTP Response', { status: res.statusText, payload, response: res });
@@ -80,7 +81,7 @@ export class BaseServiceAbstract {
80
81
  try {
81
82
  return JSON.parse(textRes);
82
83
  }
83
- catch (e) {
84
+ catch {
84
85
  this.logger.error('Failed to parse JSON from response', { textRes });
85
86
  return textRes;
86
87
  }
@@ -1,4 +1,3 @@
1
- import { splitRobotTopic } from '../helpers/splitRobotTopic';
2
1
  import { ResultStatus, RocosResponseLevel, } from '../models';
3
2
  import { Subject, map, mergeMap, take, takeUntil } from 'rxjs';
4
3
  import { filter, finalize } from 'rxjs/operators';
@@ -6,6 +5,7 @@ import { getResponses, handleChunkedMessages } from '../helpers/callerMessageHel
6
5
  import { BaseStreamService } from './BaseStreamService';
7
6
  import { CallerStream } from '../api/streams/caller/CallerStream';
8
7
  import { IDENTIFIER_NAME_CALLER } from '../constants/identifier';
8
+ import { splitRobotTopic } from '../helpers/splitRobotTopic';
9
9
  import { v4 } from 'uuid';
10
10
  export class CallerService extends BaseStreamService {
11
11
  constructor(config) {
@@ -116,9 +116,7 @@ export class PlatFormTimeService {
116
116
  let totalServerTimeOffset = 0;
117
117
  const measurementsWithValues = platformTimeMeasurements.filter((x) => !!x?.serverTime);
118
118
  measurementsWithValues.forEach((x) => {
119
- // eslint-disable-next-line operator-linebreak
120
119
  totalServerTimeOffset +=
121
- // eslint-disable-next-line no-mixed-operators
122
120
  x.clientTimeStampEnd - (x.clientTimeStampEnd - x.clientTimeStampStart) / 2 - x.serverTime.now / 10 ** 6;
123
121
  });
124
122
  // final platformTimeOffset is in miliseconds
@@ -1,5 +1,5 @@
1
1
  import { BehaviorSubject, catchError, combineLatest, distinctUntilChanged, from, interval, map, mergeAll, of, startWith, } from 'rxjs';
2
- import { CallsignStatus, CallsignsLookup, CallsignsLookupType, RocosError, TelemetryMonitorStatus, SubscriberStatusEnum, errorCodes, } from '../models';
2
+ import { CallsignStatus, CallsignsLookup, CallsignsLookupType, RocosError, SubscriberStatusEnum, TelemetryMonitorStatus, errorCodes, } from '../models';
3
3
  import { filter, finalize } from 'rxjs/operators';
4
4
  import { BaseStreamService } from './BaseStreamService';
5
5
  import { IDENTIFIER_NAME_TELEMETRY } from '../constants/identifier';
@@ -123,7 +123,7 @@ export class TelemetryService extends BaseStreamService {
123
123
  sources: [source],
124
124
  callsigns: [callsign],
125
125
  }).pipe(map(() => Date.now()));
126
- return combineLatest([heartbeatTime$.pipe(startWith(startedAt)), interval(intervalMs)]).pipe(map(([lastHeartbeat, _]) => {
126
+ return combineLatest([heartbeatTime$.pipe(startWith(startedAt)), interval(intervalMs)]).pipe(map(([lastHeartbeat]) => {
127
127
  const now = Date.now();
128
128
  // If we haven't received a heartbeat, but we've only just started
129
129
  if (lastHeartbeat === startedAt && now - startedAt <= heartbeatTimeoutMs) {
@@ -57,20 +57,20 @@ export class WebRTCSignallingService {
57
57
  return stream;
58
58
  }
59
59
  async initStream(stream) {
60
+ if (this.config.token)
61
+ return;
60
62
  // an async callback to set the stream token in case one was not set at startup
61
- if (!this.config.token) {
62
- try {
63
- const authService = RocosStore.getSDKInstance(this.config).getAuthService();
64
- const token = await authService.getToken();
65
- if (token?.value) {
66
- this.config.token = token?.value;
67
- stream.setToken(this.config.token);
68
- }
69
- }
70
- catch (e) {
71
- this.logger.info('Can not retrieve auth token for web rtc signalling stream', e);
63
+ try {
64
+ const authService = RocosStore.getSDKInstance(this.config).getAuthService();
65
+ const token = await authService.getToken();
66
+ if (token?.value) {
67
+ this.config.token = token?.value;
68
+ stream.setToken(this.config.token);
72
69
  }
73
70
  }
71
+ catch (e) {
72
+ this.logger.info('Can not retrieve auth token for web rtc signalling stream', e);
73
+ }
74
74
  }
75
75
  getStream(config) {
76
76
  return new WebRTCSignallingStream(config);
@@ -67,4 +67,11 @@ export declare class WorkflowService extends BaseServiceAbstract implements IBas
67
67
  callsigns: string[];
68
68
  profileIds: string[];
69
69
  }>;
70
+ export(projectId: string, workflowId: string): Promise<Blob>;
71
+ import(projectId: string, workflowFile: File | Blob, overrides?: {
72
+ name?: string;
73
+ description?: string;
74
+ id?: string;
75
+ type?: 'cloud' | 'default';
76
+ }): Promise<Workflow>;
70
77
  }
@@ -1,4 +1,4 @@
1
- import { API_PROJECT_PROFILE_DEPLOYED_WORKFLOW_URL, API_PROJECT_PROFILE_DEPLOYMENTS_URL, API_PROJECT_ROBOT_DEPLOYED_WORKFLOW_URL, API_PROJECT_ROBOT_DEPLOYMENTS_URL, API_PROJECT_ROBOT_NO_PROFILE_DEPLOYMENTS_URL, API_PROJECT_WORKFLOW_AFFECTED_URL, API_PROJECT_WORKFLOW_ASSET_ID_URL, API_PROJECT_WORKFLOW_ASSET_URL, API_PROJECT_WORKFLOW_ID_URL, API_PROJECT_WORKFLOW_URL, } from '../constants/api';
1
+ import { API_PROJECT_PROFILE_DEPLOYED_WORKFLOW_URL, API_PROJECT_PROFILE_DEPLOYMENTS_URL, API_PROJECT_ROBOT_DEPLOYED_WORKFLOW_URL, API_PROJECT_ROBOT_DEPLOYMENTS_URL, API_PROJECT_ROBOT_NO_PROFILE_DEPLOYMENTS_URL, API_PROJECT_WORKFLOW_AFFECTED_URL, API_PROJECT_WORKFLOW_ASSET_ID_URL, API_PROJECT_WORKFLOW_ASSET_URL, API_PROJECT_WORKFLOW_EXPORT_URL, API_PROJECT_WORKFLOW_ID_URL, API_PROJECT_WORKFLOW_IMPORT_URL, API_PROJECT_WORKFLOW_URL, } from '../constants/api';
2
2
  import { RocosError, errorCodes, } from '../models';
3
3
  import { BaseServiceAbstract } from './BaseServiceAbstract';
4
4
  import { RocosLogger } from '../logger/RocosLogger';
@@ -129,4 +129,20 @@ export class WorkflowService extends BaseServiceAbstract {
129
129
  async getAffectedRobots(projectId, workflowId) {
130
130
  return this.callGet(formatServiceUrl(API_PROJECT_WORKFLOW_AFFECTED_URL, { url: this.config.url, projectId, workflowId, flowId: workflowId }, this.config.insecure), `Failed to get affected robots for ${projectId}, workflowId ${workflowId}.`);
131
131
  }
132
+ async export(projectId, workflowId) {
133
+ return this.callPost(formatServiceUrl(API_PROJECT_WORKFLOW_EXPORT_URL, { url: this.config.url, projectId, workflowId }, this.config.insecure), undefined, `Failed to export workflow for ${projectId}, workflowId ${workflowId}.`, { responseType: 'blob' });
134
+ }
135
+ async import(projectId, workflowFile, overrides) {
136
+ const form = new FormData();
137
+ form.append('file', workflowFile);
138
+ if (overrides?.name)
139
+ form.append('name', overrides.name);
140
+ if (overrides?.description)
141
+ form.append('description', overrides.description);
142
+ if (overrides?.id)
143
+ form.append('id', overrides.id);
144
+ if (overrides?.type)
145
+ form.append('type', overrides.type);
146
+ return this.callPost(formatServiceUrl(API_PROJECT_WORKFLOW_IMPORT_URL, { url: this.config.url, projectId }, this.config.insecure), form, `Failed to import workflow for ${projectId}.`);
147
+ }
132
148
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dronedeploy/rocos-js-sdk",
3
- "version": "3.0.7",
3
+ "version": "3.0.9",
4
4
  "description": "Javascript SDK for rocos",
5
5
  "main": "cjs/index.js",
6
6
  "module": "esm/index.js",