@mindline/sync 1.0.35 → 1.0.36

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.
@@ -2,6 +2,6 @@
2
2
  "ExpandedNodes": [
3
3
  ""
4
4
  ],
5
- "SelectedNode": "\\index.ts",
5
+ "SelectedNode": "\\hybridspa.ts",
6
6
  "PreviewInSolutionExplorer": false
7
7
  }
package/.vs/slnx.sqlite CHANGED
Binary file
Binary file
package/hybridspa.ts CHANGED
@@ -863,14 +863,12 @@ export async function readerPost(
863
863
  return result;
864
864
  }
865
865
  // create reader endpoint with config ID
866
- //let readerEndpoint: string = graphConfig.readerStartSyncEndpoint + config.id;
867
- let readerEndpoint: string = graphConfig.readerApiEndpoint + config.id;
866
+ let readerEndpoint: string = graphConfig.readerStartSyncEndpoint + config.id;
868
867
  // create headers
869
868
  const headers = await defineHeaders(instance, authorizedUser);
870
869
  // make reader endpoint call
871
870
  let options = { method: "POST", headers: headers };
872
871
  try {
873
- debugger;
874
872
  console.log("Attempting POST to /startSync: " + readerEndpoint);
875
873
  let response = await fetch(readerEndpoint, options);
876
874
  if (response.status === 200 && response.statusText === "OK") {
package/index.d.ts CHANGED
@@ -1,187 +1,186 @@
1
1
  import { IPublicClientApplication } from "@azure/msal-browser";
2
2
 
3
3
  declare module "@mindline/sync" {
4
- export function sum(a: number, b: number): number;
5
- export function helloNpm(): string;
4
+ export function sum(a: number, b: number): number;
5
+ export function helloNpm(): string;
6
6
 
7
- export class Group {
8
- id: string;
9
- displayName: string;
10
- description: string;
11
- }
12
- // admin
13
- export class User {
14
- oid: string; // from AAD ID token
15
- name: string; // from AAD ID token
16
- mail: string; // from AAD ID token TODO: preferred_username *may* differ from UPN, may differ from mail
17
- authority: string; // from AAD auth response - cloud instance login endpoint
18
- tid: string; // from AAD ID token
19
- companyName: string; // findTenantInformationByTenantId TODO: process changes to company name
20
- companyDomain: string; // findTenantInformationByTenantId TODO: process changes to company name
21
- associatedWorkspaces: string[];
22
- workspaceIDs: string;
23
- session: string;
24
- spacode: string;
25
- accessToken: string;
26
- loginHint: string;
27
- scopes: string[];
28
- authTS: Date;
29
- constructor();
30
- }
31
- // tenant (Azure AD tenant, AD domain, Google workspace)
32
- export enum TenantType {
33
- invalid = 0,
34
- aad = 1,
35
- ad = 2,
36
- googleworkspace = 3
37
- }
38
- type TenantTypeStrings = keyof typeof TenantType;
39
- export enum TenantPermissionType {
40
- read = 1,
41
- write = 2,
42
- notassigned = 3
43
- }
44
- type TenantPermissionTypeStrings = keyof typeof TenantPermissionType;
45
- export class Tenant {
46
- tid: string; // from AAD ID token
47
- name: string; // findTenantInformationByTenantId
48
- domain: string; // findTenantInformationByTenantId
49
- tenantType: TenantTypeStrings; // always "aad" for now
50
- permissionType: TenantPermissionTypeStrings; // read/write/notassigned
51
- onboarded: string; // have we onboarded this tenant? "true" or "false"
52
- authority: string; // from AAD ID auth response
53
- readServicePrincipal: string; // from AAD consent
54
- writeServicePrincipal: string; // from AAD consent
55
- workspaceIDs: string;
56
- constructor();
57
- }
58
- // config
59
- export enum TenantConfigType {
60
- source = 1,
61
- target = 2,
62
- sourcetarget = 3
63
- }
64
- export type TenantConfigTypeStrings = keyof typeof TenantConfigType;
65
- export class TenantConfigInfo {
66
- tid: string; // tenant identifier
67
- sourceGroupId: string; // source group - we can configure source group for reading
68
- sourceGroupName: string; // source group - we can configure source group for reading
69
- configurationTenantType: TenantConfigTypeStrings;
70
- deltaToken: string;
71
- filesWritten: number;
72
- }
73
- export class Config {
74
- id: string;
75
- workspaceId: string;
76
- name: string;
77
- description: string;
78
- tenants: TenantConfigInfo[];
79
- isEnabled: boolean;
80
- workspaceIDs: string;
81
- constructor();
82
- }
83
- // class to group Users, Tenants, and Configs
84
- export class Workspace {
85
- id: string;
86
- name: string;
87
- associatedUsers: string[];
88
- associatedTenants: string[];
89
- associatedConfigs: string[];
90
- constructor();
91
- }
92
- export class InitInfo {
93
- us: User[];
94
- ts: Tenant[];
95
- cs: Config[];
96
- ws: Workspace[];
97
- constructor(bClearLocalStorage: boolean);
98
- init(bClearLocalStorage: boolean): void;
99
- save(): void;
100
- tagWithWorkspaces(): boolean;
101
- }
102
- export type TaskType = "initialization" |
7
+ export class Group {
8
+ id: string;
9
+ displayName: string;
10
+ description: string;
11
+ }
12
+ // admin
13
+ export class User {
14
+ oid: string; // from AAD ID token
15
+ name: string; // from AAD ID token
16
+ mail: string; // from AAD ID token TODO: preferred_username *may* differ from UPN, may differ from mail
17
+ authority: string; // from AAD auth response - cloud instance login endpoint
18
+ tid: string; // from AAD ID token
19
+ companyName: string; // findTenantInformationByTenantId TODO: process changes to company name
20
+ companyDomain: string; // findTenantInformationByTenantId TODO: process changes to company name
21
+ associatedWorkspaces: string[];
22
+ workspaceIDs: string;
23
+ session: string;
24
+ spacode: string;
25
+ accessToken: string;
26
+ loginHint: string;
27
+ scopes: string[];
28
+ authTS: Date;
29
+ constructor();
30
+ }
31
+ // tenant (Azure AD tenant, AD domain, Google workspace)
32
+ export enum TenantType {
33
+ invalid = 0,
34
+ aad = 1,
35
+ ad = 2,
36
+ googleworkspace = 3
37
+ }
38
+ type TenantTypeStrings = keyof typeof TenantType;
39
+ export enum TenantPermissionType {
40
+ read = 1,
41
+ write = 2,
42
+ notassigned = 3
43
+ }
44
+ type TenantPermissionTypeStrings = keyof typeof TenantPermissionType;
45
+ export class Tenant {
46
+ tid: string; // from AAD ID token
47
+ name: string; // findTenantInformationByTenantId
48
+ domain: string; // findTenantInformationByTenantId
49
+ tenantType: TenantTypeStrings; // always "aad" for now
50
+ permissionType: TenantPermissionTypeStrings; // read/write/notassigned
51
+ onboarded: string; // have we onboarded this tenant? "true" or "false"
52
+ authority: string; // from AAD ID auth response
53
+ readServicePrincipal: string; // from AAD consent
54
+ writeServicePrincipal: string; // from AAD consent
55
+ workspaceIDs: string;
56
+ constructor();
57
+ }
58
+ // config
59
+ export enum TenantConfigType {
60
+ source = 1,
61
+ target = 2,
62
+ sourcetarget = 3
63
+ }
64
+ export type TenantConfigTypeStrings = keyof typeof TenantConfigType;
65
+ export class TenantConfigInfo {
66
+ tid: string; // tenant identifier
67
+ sourceGroupId: string; // source group - we can configure source group for reading
68
+ sourceGroupName: string; // source group - we can configure source group for reading
69
+ configurationTenantType: TenantConfigTypeStrings;
70
+ deltaToken: string;
71
+ filesWritten: number;
72
+ configId: string;
73
+ }
74
+ export class Config {
75
+ id: string;
76
+ workspaceId: string;
77
+ name: string;
78
+ description: string;
79
+ tenants: TenantConfigInfo[];
80
+ isEnabled: boolean;
81
+ workspaceIDs: string;
82
+ constructor();
83
+ }
84
+ // class to group Users, Tenants, and Configs
85
+ export class Workspace {
86
+ id: string;
87
+ name: string;
88
+ associatedUsers: string[];
89
+ associatedTenants: string[];
90
+ associatedConfigs: string[];
91
+ constructor();
92
+ }
93
+ export class InitInfo {
94
+ us: User[];
95
+ ts: Tenant[];
96
+ cs: Config[];
97
+ ws: Workspace[];
98
+ constructor(bClearLocalStorage: boolean);
99
+ init(bClearLocalStorage: boolean): void;
100
+ save(): void;
101
+ tagWithWorkspaces(): boolean;
102
+ }
103
+ export type TaskType = "initialization" |
103
104
  "authenticate user" |
104
105
  "reload React" |
105
106
  "PUT access token" |
106
107
  "GET tenant details" |
107
108
  "POST config init" |
108
109
  "GET workspaces" |
109
- "onboard tenant" |
110
- "create 2nd tenant" |
111
- "invite 2nd admin" |
112
- "onboard 2nd tenant" |
113
- "create config";
114
- export class TaskArray {
115
- tasks: Task[];
116
- constructor(bClearLocalStorage: boolean);
117
- init(bClearLocalStorage: boolean): void;
118
- setTaskStart(taskType: TaskType, startDate: Date): void;
119
- setTaskEnd(taskType: TaskType, startDate: Date, status: string): void;
120
- }
121
- export class Task {
122
- id: number;
123
- task: string;
124
- start: Date;
125
- startDisplay: string;
126
- end: Date;
127
- endDisplay: string;
128
- elapsedDisplay: string;
129
- expected: number;
130
- status: string;
131
- expanded: boolean;
132
- subtasks: Task[];
133
- setEnd(endDate: Date): void;
134
- setStart(startDate: Date): void;
135
- }
136
- export class BatchArray {
137
- tenantNodes: TenantNode[];
138
- constructor(config: Config|null, syncPortalGlobalState: InitInfo|null, bClearLocalStorage: boolean);
139
- // populate tenantNodes based on config tenants
140
- init(config: Config|null, syncPortalGlobalState: InitInfo|null, bClearLocalStorage: boolean): void;
141
- startSync(instance: IPublicClientApplication, authorizedUser: User|null|undefined, config: Config|null|undefined): void;
142
- }
143
- export class TenantNode {
144
- expanded: boolean;
145
- status: string;
146
- name: string;
147
- tid: string;
148
- total: number;
149
- read: number;
150
- written: number;
151
- deferred: number;
152
- targets: TenantNode[];
153
- constructor(tid: string, name: string);
154
- update(total: number, read: number, written: number, deferred: number): void;
155
- }
156
- export class APIResult {
157
- result: boolean;
158
- status: number;
159
- error: string;
160
- constructor();
161
- }
162
- //
163
- // Azure AD Graph API
164
- //
165
- export function groupGet(tenant: Tenant, groupid: string): Promise<{group: string, error: string}>;
166
- export function groupsGet(tenant: Tenant, groupSearchString: string): Promise<{groups: Group[], error: string}>;
167
- export function signIn(user: User, tasks: TaskArray): void;
168
- export function signInIncrementally(user: User, scope: string): void;
169
- export function signOut(user: User): void;
170
- export function tenantRelationshipsGetByDomain(loggedInuser: User, tenant: Tenant, instance: IPublicClientApplication, debug: boolean): boolean;
171
- export function tenantRelationshipsGetById(user: User, ii: InitInfo, instance: IPublicClientApplication, tasks: TaskArray, debug: boolean): boolean;
172
- export function usersGet(tenant: Tenant): {users: string[], error: string};
173
- //
174
- // Mindline Config API
175
- //
176
- export function configEdit(instance: IPublicClientApplication, authorizedUser: User, config: Config, workspaceId: string, debug: boolean): APIResult;
177
- export function configRemove(instance: IPublicClientApplication, authorizedUser: User, config: Config, workspaceId: string, debug: boolean): APIResult;
178
- export function initGet(instance: IPublicClientApplication, authorizedUser: User, user: User, ii: InitInfo, tasks: TaskArray, debug: boolean): APIResult;
179
- export function tenantAdd(instance: IPublicClientApplication, authorizedUser: User, tenant: Tenant, workspaceId: string): APIResult;
180
- export function tenantComplete(instance: IPublicClientApplication, authorizedUser: User, tenant: Tenant, debug: boolean): APIResult;
181
- export function tenantRemove(instance: IPublicClientApplication, authorizedUser: User, tenant: Tenant, workspaceId: string, debug: boolean): APIResult;
182
- export function userAdd(instance: IPublicClientApplication, authorizedUser: User, user: User, workspaceId: string): APIResult;
110
+ "onboard tenant" |
111
+ "create 2nd tenant" |
112
+ "invite 2nd admin" |
113
+ "onboard 2nd tenant" |
114
+ "create config";
115
+ export class TaskArray {
116
+ tasks: Task[];
117
+ constructor(bClearLocalStorage: boolean);
118
+ init(bClearLocalStorage: boolean): void;
119
+ setTaskStart(taskType: TaskType, startDate: Date): void;
120
+ setTaskEnd(taskType: TaskType, startDate: Date, status: string): void;
121
+ }
122
+ export class Task {
123
+ id: number;
124
+ task: string;
125
+ start: Date;
126
+ startDisplay: string;
127
+ end: Date;
128
+ endDisplay: string;
129
+ elapsedDisplay: string;
130
+ expected: number;
131
+ status: string;
132
+ expanded: boolean;
133
+ subtasks: Task[];
134
+ setEnd(endDate: Date): void;
135
+ setStart(startDate: Date): void;
136
+ }
137
+ export class BatchArray {
138
+ tenantNodes: TenantNode[];
139
+ constructor(config: Config|null, syncPortalGlobalState: InitInfo|null, bClearLocalStorage: boolean);
140
+ // populate tenantNodes based on config tenants
141
+ init(config: Config|null, syncPortalGlobalState: InitInfo|null, bClearLocalStorage: boolean): void;
142
+ startSync(instance: IPublicClientApplication, authorizedUser: User|null|undefined, config: Config|null|undefined): void;
143
+ }
144
+ export class TenantNode {
145
+ expanded: boolean;
146
+ status: string;
147
+ name: string;
148
+ tid: string;
149
+ total: number;
150
+ read: number;
151
+ written: number;
152
+ deferred: number;
153
+ targets: TenantNode[];
154
+ constructor(tid: string, name: string);
155
+ update(total: number, read: number, written: number, deferred: number): void;
156
+ }
157
+ export class APIResult {
158
+ result: boolean;
159
+ status: number;
160
+ error: string;
161
+ constructor();
162
+ }
163
+ //
164
+ // Azure AD Graph API
165
+ //
166
+ export function groupGet(tenant: Tenant, groupid: string): Promise<{group: string, error: string}>;
167
+ export function groupsGet(tenant: Tenant, groupSearchString: string): Promise<{groups: Group[], error: string}>;
168
+ export function signIn(user: User, tasks: TaskArray): void;
169
+ export function signInIncrementally(user: User, scope: string): void;
170
+ export function signOut(user: User): void;
171
+ export function tenantRelationshipsGetByDomain(loggedInuser: User, tenant: Tenant, instance: IPublicClientApplication, debug: boolean): boolean;
172
+ export function tenantRelationshipsGetById(user: User, ii: InitInfo, instance: IPublicClientApplication, tasks: TaskArray, debug: boolean): boolean;
173
+ export function usersGet(tenant: Tenant): {users: string[], error: string};
174
+ //
175
+ // Mindline Config API
176
+ //
177
+ export function configEdit(instance: IPublicClientApplication, authorizedUser: User, config: Config, workspaceId: string, debug: boolean): APIResult;
178
+ export function configRemove(instance: IPublicClientApplication, authorizedUser: User, config: Config, workspaceId: string, debug: boolean): APIResult;
179
+ export function configsRefresh(instance: IPublicClientApplication, authorizedUser: User, workspaceId: string, ii: InitInfo, debug: boolean): APIResult;
180
+ export function initGet(instance: IPublicClientApplication, authorizedUser: User, user: User, ii: InitInfo, tasks: TaskArray, debug: boolean): APIResult;
181
+ export function tenantAdd(instance: IPublicClientApplication, authorizedUser: User, tenant: Tenant, workspaceId: string): APIResult;
182
+ export function tenantComplete(instance: IPublicClientApplication, authorizedUser: User, tenant: Tenant, debug: boolean): APIResult;
183
+ export function tenantRemove(instance: IPublicClientApplication, authorizedUser: User, tenant: Tenant, workspaceId: string, debug: boolean): APIResult;
184
+ export function userAdd(instance: IPublicClientApplication, authorizedUser: User, user: User, workspaceId: string): APIResult;
183
185
  export function userRemove(instance: IPublicClientApplication, authorizedUser: User, user: User, workspaceId: string): APIResult;
184
- //
185
- // Mindline Sync API
186
- //
187
186
  }
package/index.ts CHANGED
@@ -106,6 +106,7 @@ export class TenantConfigInfo {
106
106
  configurationTenantType: TenantConfigTypeStrings;
107
107
  deltaToken: string;
108
108
  filesWritten: number;
109
+ configId: string;
109
110
  constructor() {
110
111
  this.tid = "";
111
112
  this.sourceGroupId = "";
@@ -113,6 +114,7 @@ export class TenantConfigInfo {
113
114
  this.configurationTenantType = "source";
114
115
  this.deltaToken = "";
115
116
  this.filesWritten = 0;
117
+ this.configId = "";
116
118
  }
117
119
  }
118
120
  export class Config {
@@ -647,18 +649,25 @@ export class BatchArray {
647
649
  }
648
650
  }
649
651
  */
650
- // cycle through test state machine
652
+ // start a sync cycle
651
653
  startSync(instance: IPublicClientApplication, authorizedUser: User | null | undefined, config: Config | null | undefined): void {
652
654
  if (this.tenantNodes == null || this.tenantNodes.length == 0) {
653
655
  // we should not have an empty batch array for a test
654
656
  debugger;
655
657
  }
658
+ // start SignalR connection
659
+ const connection = new signalR.HubConnectionBuilder() // SignalR initialization
660
+ .withUrl("https://dev-signalrdispatcher-westus.azurewebsites.net/statsHub?statsId=df9c2e0a-f6fe-43bb-a155-d51f66dffe0e", { skipNegotiation: true, transport: signalR.HttpTransportType.WebSockets } )
661
+ .configureLogging(signalR.LogLevel.Information)
662
+ .build();
663
+ // when you get a message, log the message
664
+ connection.on("newMessage", function (message) {
665
+ console.log(message); // log the message
666
+ });
667
+ connection.start().catch(console.error);
656
668
  // execute post to reader endpoint
657
669
  readerPost(instance, authorizedUser, config);
658
-
659
- // start SignalR connection
660
- //debugger;
661
- //monitorSyncProgress();
670
+ // refresh delta tokens for this Configuration (we read all Configurations at once)
662
671
  }
663
672
  }
664
673
  export class TenantNode {
@@ -970,6 +979,34 @@ export async function configEdit(instance: IPublicClientApplication, authorizedU
970
979
  export async function configRemove(instance: IPublicClientApplication, authorizedUser: User, config: Config, workspaceId: string, debug: boolean): Promise<APIResult> {
971
980
  return configDelete(instance, authorizedUser, config, workspaceId, debug);
972
981
  }
982
+ export async function configsRefresh(instance: IPublicClientApplication, authorizedUser: User, workspaceId: string, ii: InitInfo, debug: boolean): Promise<APIResult> {
983
+ let result: APIResult = new APIResult();
984
+ if (debug) debugger;
985
+ try {
986
+ let workspace: Workspace = ii.ws.find((w) => w.id === workspaceId);
987
+ if (workspace != null) {
988
+ // clear Config associations as we are about to reset
989
+ workspace.associatedConfigs.length = 0;
990
+ // GET configs associated with this workspace
991
+ let configsPromise: Promise<APIResult> = configsGet(instance, authorizedUser, workspace.id, debug);
992
+ // wait for query to finish, return on any failure
993
+ let [configsResult] = await Promise.all([configsPromise]);
994
+ if (!configsResult.result) return configsResult;
995
+ // process returned workspace components
996
+ processReturnedConfigs(workspace, ii, configsResult.array!);
997
+ // tag components with workspaceIDs
998
+ ii.tagWithWorkspaces();
999
+ }
1000
+ return result;
1001
+ }
1002
+ catch (error: any) {
1003
+ console.log(error.message);
1004
+ result.error = error.message;
1005
+ }
1006
+ result.result = false;
1007
+ result.status = 500;
1008
+ return result;
1009
+ }
973
1010
  // retrieve Workspace(s), User(s), Tenant(s), Config(s) given newly logged in user
974
1011
  export async function initGet(instance: IPublicClientApplication, authorizedUser: User, user: User, ii: InitInfo, tasks: TaskArray, debug: boolean): Promise<APIResult> {
975
1012
  let result: APIResult = new APIResult();
@@ -989,6 +1026,7 @@ export async function initGet(instance: IPublicClientApplication, authorizedUser
989
1026
  tasks.setTaskEnd("GET workspaces", new Date(), result.result ? "complete" : "failed");
990
1027
  }
991
1028
  if (result.result) result.error = version;
1029
+ else console.log("@mindline/sync package version: " + version);
992
1030
  return result;
993
1031
  }
994
1032
  export async function tenantAdd(instance: IPublicClientApplication, authorizedUser: User, tenant: Tenant, workspaceId: string): Promise<APIResult> {
@@ -1109,6 +1147,7 @@ function processReturnedConfigs(workspace: Workspace, ii: InitInfo, returnedConf
1109
1147
  tenantConfigInfo.sourceGroupName = tci.sourceGroupName;
1110
1148
  tenantConfigInfo.configurationTenantType = tci.configurationTenantType.toLowerCase();
1111
1149
  tenantConfigInfo.deltaToken = tci.deltaToken ?? "";
1150
+ tenantConfigInfo.configId = config!.id;
1112
1151
  config!.tenants.push(tenantConfigInfo);
1113
1152
  });
1114
1153
  // ensure this workspace tracks this config
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mindline/sync",
3
3
  "type": "module",
4
- "version": "1.0.35",
4
+ "version": "1.0.36",
5
5
  "types": "index.d.ts",
6
6
  "exports": "./index.ts",
7
7
  "description": "sync is a node.js package encapsulating javscript classes required for configuring Mindline sync service.",
@@ -16,6 +16,7 @@
16
16
  "vitest": "^0.29.8"
17
17
  },
18
18
  "dependencies": {
19
+ "@microsoft/signalr": "^7.0.10",
19
20
  "class-transformer": "^0.5.1",
20
21
  "reflect-metadata": "^0.1.13"
21
22
  }