@tellescope/sdk 0.0.13 → 0.0.17

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.
Files changed (44) hide show
  1. package/lib/cjs/enduser.d.ts +29 -3
  2. package/lib/cjs/enduser.d.ts.map +1 -1
  3. package/lib/cjs/enduser.js +1 -1
  4. package/lib/cjs/enduser.js.map +1 -1
  5. package/lib/cjs/sdk.d.ts +45 -12
  6. package/lib/cjs/sdk.d.ts.map +1 -1
  7. package/lib/cjs/sdk.js +5 -4
  8. package/lib/cjs/sdk.js.map +1 -1
  9. package/lib/cjs/session.d.ts +1 -0
  10. package/lib/cjs/session.d.ts.map +1 -1
  11. package/lib/cjs/session.js +11 -0
  12. package/lib/cjs/session.js.map +1 -1
  13. package/lib/cjs/tests/public_endpoint_tests.js +3 -3
  14. package/lib/cjs/tests/public_endpoint_tests.js.map +1 -1
  15. package/lib/cjs/tests/socket_tests.js +1 -1
  16. package/lib/cjs/tests/socket_tests.js.map +1 -1
  17. package/lib/cjs/tests/tests.js +97 -17
  18. package/lib/cjs/tests/tests.js.map +1 -1
  19. package/lib/esm/enduser.d.ts +29 -3
  20. package/lib/esm/enduser.d.ts.map +1 -1
  21. package/lib/esm/enduser.js +1 -1
  22. package/lib/esm/enduser.js.map +1 -1
  23. package/lib/esm/sdk.d.ts +45 -12
  24. package/lib/esm/sdk.d.ts.map +1 -1
  25. package/lib/esm/sdk.js +5 -4
  26. package/lib/esm/sdk.js.map +1 -1
  27. package/lib/esm/session.d.ts +1 -0
  28. package/lib/esm/session.d.ts.map +1 -1
  29. package/lib/esm/session.js +11 -0
  30. package/lib/esm/session.js.map +1 -1
  31. package/lib/esm/tests/public_endpoint_tests.js +3 -3
  32. package/lib/esm/tests/public_endpoint_tests.js.map +1 -1
  33. package/lib/esm/tests/socket_tests.js +1 -1
  34. package/lib/esm/tests/socket_tests.js.map +1 -1
  35. package/lib/esm/tests/tests.js +78 -17
  36. package/lib/esm/tests/tests.js.map +1 -1
  37. package/lib/tsconfig.tsbuildinfo +1 -1
  38. package/package.json +10 -10
  39. package/src/enduser.ts +2 -2
  40. package/src/sdk.ts +12 -9
  41. package/src/session.ts +5 -0
  42. package/src/tests/public_endpoint_tests.ts +3 -3
  43. package/src/tests/socket_tests.ts +1 -1
  44. package/src/tests/tests.ts +74 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tellescope/sdk",
3
- "version": "0.0.13",
3
+ "version": "0.0.17",
4
4
  "description": "Code for interacting with the Tellescope API",
5
5
  "main": "./lib/cjs/sdk.js",
6
6
  "module": "./lib/esm/sdk.js",
@@ -30,14 +30,14 @@
30
30
  },
31
31
  "homepage": "https://github.com/tellescope-os/tellescope#readme",
32
32
  "dependencies": {
33
- "@tellescope/constants": "^0.0.13",
34
- "@tellescope/schema": "^0.0.13",
35
- "@tellescope/testing": "^0.0.13",
36
- "@tellescope/types-client": "^0.0.13",
37
- "@tellescope/types-models": "^0.0.13",
38
- "@tellescope/types-utilities": "^0.0.13",
39
- "@tellescope/utilities": "^0.0.13",
40
- "@tellescope/validation": "^0.0.13",
33
+ "@tellescope/constants": "^0.0.17",
34
+ "@tellescope/schema": "^0.0.17",
35
+ "@tellescope/testing": "^0.0.17",
36
+ "@tellescope/types-client": "^0.0.17",
37
+ "@tellescope/types-models": "^0.0.17",
38
+ "@tellescope/types-utilities": "^0.0.17",
39
+ "@tellescope/utilities": "^0.0.17",
40
+ "@tellescope/validation": "^0.0.17",
41
41
  "axios": "^0.21.1",
42
42
  "form-data": "^4.0.0",
43
43
  "socket.io-client": "^4.2.0",
@@ -53,5 +53,5 @@
53
53
  "publishConfig": {
54
54
  "access": "public"
55
55
  },
56
- "gitHead": "1eb38568bd39b941e6b4a2bad9e3b33841c26b39"
56
+ "gitHead": "4f6785b4e580de4f3fceb9bc3d455cc7191cd094"
57
57
  }
package/src/enduser.ts CHANGED
@@ -42,7 +42,7 @@ type EnduserQueries = { [K in EnduserAccessibleModels]: APIQuery<K> } & {
42
42
  logout: () => Promise<void>;
43
43
  },
44
44
  users: {
45
- display_names: () => Promise<{ fname: string, lname: string, id: string }[]>
45
+ display_info: () => Promise<{ fname?: string, lname?: string, id: string, lastActive?: Date, lastLogout?: Date }[]>
46
46
  },
47
47
  files: {
48
48
  prepare_file_upload: (args: { name: string, size: number, type: string }) => Promise<{ presignedUpload: S3PresignedPost, file: File }>,
@@ -76,7 +76,7 @@ export class EnduserSession extends Session {
76
76
  logout: () => this._POST('/v1/logout-enduser'),
77
77
  }
78
78
  this.api.users = {
79
- display_names: () => this._GET<{}, { fname: string, lname: string, id: string }[] >(`/v1/user-display-names`),
79
+ display_info: () => this._GET<{}, { fname: string, lname: string, id: string }[] >(`/v1/user-display-info`),
80
80
  }
81
81
  this.api.meetings = {
82
82
  attendee_info: a => this._GET('/v1/attendee-info', a),
package/src/sdk.ts CHANGED
@@ -24,6 +24,8 @@ import { Session as SessionManager, SessionOptions, Filter } from "./session"
24
24
  export * from "./public"
25
25
  export * from "./enduser"
26
26
 
27
+ export type LoadFunction<T> = (o?: { lastId?: string, limit?: number, sort?: SortOption, threadKey?: string, filter?: Filter<Partial<T>> }) => Promise<T[]>
28
+
27
29
  export interface APIQuery<
28
30
  N extends keyof ClientModelForName,
29
31
  T=ClientModelForName[N],
@@ -35,7 +37,7 @@ export interface APIQuery<
35
37
  createOne: (t: CREATE) => Promise<T>;
36
38
  createSome: (ts: CREATE[]) => Promise<{ created: T[], errors: object[] }>;
37
39
  getOne: (id: string, filter?: Filter<Partial<T>>) => Promise<T>;
38
- getSome: (o?: { lastId?: string, limit?: number, sort?: SortOption, threadKey?: string, filter?: Filter<Partial<T>> }) => Promise<T[]>
40
+ getSome: LoadFunction<T>;
39
41
  updateOne: (id: string, updates: UPDATE, options?: CustomUpdateOptions) => Promise<T>;
40
42
  deleteOne: (id: string) => Promise<void>;
41
43
  }
@@ -72,16 +74,17 @@ const loadDefaultQueries = (s: Session): { [K in keyof ClientModelForName] : API
72
74
  files: defaultQueries(s, 'files'),
73
75
  tickets: defaultQueries(s, 'tickets'),
74
76
  meetings: defaultQueries(s, 'meetings'),
77
+ notes: defaultQueries(s, 'notes'),
75
78
  })
76
79
 
77
80
  type Queries = { [K in keyof ClientModelForName]: APIQuery<K> } & {
78
81
  journeys: {
79
- updateState: (args: { id: string, name: string, updates: JourneyState }) => Promise<void>
82
+ update_state: (args: { id: string, name: string, updates: JourneyState }) => Promise<void>
80
83
  },
81
84
  endusers: {
82
- setPassword: (args: { id: string, password: string }) => Promise<void>,
83
- isAuthenticated: (args: { id: string, authToken: string }) => Promise<{ isAuthenticated: boolean, enduser: Enduser }>
84
- generateAuthToken: (args: { id: string }) => Promise<{ authToken: string }>
85
+ set_password: (args: { id: string, password: string }) => Promise<void>,
86
+ is_authenticated: (args: { id: string, authToken: string }) => Promise<{ isAuthenticated: boolean, enduser: Enduser }>
87
+ generate_auth_token: (args: { id?: string, phone?: string, email?: string, externalId?: string }) => Promise<{ authToken: string, enduser: Enduser }>
85
88
  },
86
89
  users: {
87
90
  display_names: () => Promise<{ fname: string, lname: string, id: string }[]>,
@@ -110,10 +113,10 @@ export class Session extends SessionManager {
110
113
  super({ ...o, cacheKey: o?.cacheKey || "tellescope_user" })
111
114
  const queries = loadDefaultQueries(this) as Queries
112
115
 
113
- queries.journeys.updateState = ({id, name, updates}) => this._PATCH(`/v1/journey/${id}/state/${name}`, { updates })
114
- queries.endusers.setPassword = ({id, password}) => this._POST(`/v1/set-enduser-password`, { id, password })
115
- queries.endusers.isAuthenticated = ({id, authToken}) => this._GET(`/v1/enduser-is-authenticated`, { id, authToken })
116
- queries.endusers.generateAuthToken = args => this._GET(`/v1/generate-enduser-auth-token`, args)
116
+ queries.journeys.update_state = ({id, name, updates}) => this._PATCH(`/v1/journey/${id}/state/${name}`, { updates })
117
+ queries.endusers.set_password = ({id, password}) => this._POST(`/v1/set-enduser-password`, { id, password })
118
+ queries.endusers.is_authenticated = ({id, authToken}) => this._GET(`/v1/enduser-is-authenticated`, { id, authToken })
119
+ queries.endusers.generate_auth_token = args => this._GET(`/v1/generate-enduser-auth-token`, args)
117
120
  queries.users.display_names = () => this._GET<{}, { fname: string, lname: string, id: string }[]>(`/v1/user-display-names`),
118
121
  queries.files.prepare_file_upload = (args) => this._POST(`/v1/prepare-file-upload`, args),
119
122
  queries.files.file_download_URL = a => this._GET('/v1/file-download-URL', a),
package/src/session.ts CHANGED
@@ -195,6 +195,11 @@ export class Session {
195
195
  catch(err) { console.error(err); throw err }
196
196
  }
197
197
 
198
+ DOWNLOAD = async (downloadURL: string) => {
199
+ const content = await axios.get(downloadURL)
200
+ return content.data
201
+ }
202
+
198
203
  EMIT = async (route: string, args: object, authenticated=true, options={} as RequestOptions) => {
199
204
  this.socket?.emit(route, { ...args, ...authenticated ? { authToken: this.authToken } : {} } )
200
205
  }
@@ -32,14 +32,14 @@ const enduser_login_tests = async () => {
32
32
  )
33
33
  await async_test(
34
34
  'setPassword',
35
- () => sdk.api.endusers.setPassword({ id: e.id, password }),
35
+ () => sdk.api.endusers.set_password({ id: e.id, password }),
36
36
  { onResult: _ => true }
37
37
  )
38
38
 
39
39
  let authToken = 'placeholder'
40
40
  await async_test(
41
41
  'isAuthenticated (no)',
42
- () => sdk.api.endusers.isAuthenticated({ id: e.id, authToken }),
42
+ () => sdk.api.endusers.is_authenticated({ id: e.id, authToken }),
43
43
  { onResult: ({ isAuthenticated, enduser }) => isAuthenticated === false && enduser === null }
44
44
  )
45
45
  await async_test(
@@ -49,7 +49,7 @@ const enduser_login_tests = async () => {
49
49
  )
50
50
  await async_test(
51
51
  'isAuthenticated (yes)',
52
- () => sdk.api.endusers.isAuthenticated({ id: e.id, authToken }),
52
+ () => sdk.api.endusers.is_authenticated({ id: e.id, authToken }),
53
53
  { onResult: ({ isAuthenticated, enduser }) => isAuthenticated === true && enduser?.id === e.id }
54
54
  )
55
55
  }
@@ -133,7 +133,7 @@ const access_tests = async () => {
133
133
 
134
134
  const enduser_tests = async () => {
135
135
  const enduser = await user1.api.endusers.createOne({ email: "enduser@tellescope.com" })
136
- await user1.api.endusers.setPassword({ id: enduser.id, password: 'enduserPassword!' })
136
+ await user1.api.endusers.set_password({ id: enduser.id, password: 'enduserPassword!' })
137
137
 
138
138
  await enduserSDK.authenticate(enduser.email as string, 'enduserPassword!')
139
139
  await wait(undefined, 25)
@@ -1,4 +1,6 @@
1
1
  require('source-map-support').install();
2
+ import * as fs from "fs"
3
+ import * as buffer from "buffer" // only node >=15.7.0
2
4
 
3
5
  import {
4
6
  Enduser,
@@ -190,7 +192,7 @@ const threadKeyTests = async () => {
190
192
  }
191
193
 
192
194
  const filterTests = async () => {
193
- const enduser = await sdk.api.endusers.createOne({ email: 'filtertests@tellescope.com', fname: 'test' })
195
+ const enduser = await sdk.api.endusers.createOne({ email: 'filtertests@tellescope.com', fname: 'test', fields: { field1: 'value1', field2: 'value2' } })
194
196
  const otherEnduser = await sdk.api.endusers.createOne({ email: 'other@tellescope.com' })
195
197
  await async_test(
196
198
  `find enduser by filter`,
@@ -212,6 +214,36 @@ const filterTests = async () => {
212
214
  () => sdk.api.endusers.getSome({ filter: { email: 'doesnotexist@tellescope.com' }}),
213
215
  { onResult: es => es.length === 0 },
214
216
  )
217
+ await async_test(
218
+ `find enduser by nested filter`,
219
+ () => sdk.api.endusers.getSome({ filter: { fields: { field1: 'value1' } } }),
220
+ { onResult: es => es.length === 1 && es[0].id === enduser.id },
221
+ )
222
+ await async_test(
223
+ `nothing found by invalid nested filter`,
224
+ () => sdk.api.endusers.getSome({ filter: { fields: { field1: 'not a nested field value' } }}),
225
+ { onResult: es => es.length === 0 },
226
+ )
227
+ await async_test(
228
+ `find enduser by compound nested filter`,
229
+ () => sdk.api.endusers.getSome({ filter: { fields: { field1: 'value1', field2: 'value2' } } }),
230
+ { onResult: es => es.length === 1 && es[0].id === enduser.id },
231
+ )
232
+ await async_test(
233
+ `nothing found by compound invalid nested filter`,
234
+ () => sdk.api.endusers.getSome({ filter: { fields: { field1: 'not a nested field value', field2: 'value2' } }}),
235
+ { onResult: es => es.length === 0 },
236
+ )
237
+ await async_test(
238
+ `find enduser by compound nested filter with non-nested field as well`,
239
+ () => sdk.api.endusers.getSome({ filter: {email: 'filtertests@tellescope.com', fields: { field1: 'value1', field2: 'value2' } } }),
240
+ { onResult: es => es.length === 1 && es[0].id === enduser.id },
241
+ )
242
+ await async_test(
243
+ `nothing found for compound nested filter with non-nested field as well`,
244
+ () => sdk.api.endusers.getSome({ filter: {email: 'doesnotexist@tellescope.com', fields: { field1: 'value1', field2: 'value2' } } }),
245
+ { onResult: es => es.length === 0 },
246
+ )
215
247
 
216
248
  await sdk.api.endusers.deleteOne(enduser.id)
217
249
  await sdk.api.endusers.deleteOne(otherEnduser.id)
@@ -233,11 +265,31 @@ const updatesTests = async () => {
233
265
 
234
266
  const generateEnduserAuthTests = async () => {
235
267
  log_header("Generated Enduser authToken Tests")
236
- const enduser = await sdk.api.endusers.createOne({ email: 'generated@tellescope.com'})
237
- const { authToken } = await sdk.api.endusers.generateAuthToken({ id: enduser.id })
238
- const { isAuthenticated } = await sdk.api.endusers.isAuthenticated({ id: enduser.id, authToken })
268
+ const e = await sdk.api.endusers.createOne({ email: 'generated@tellescope.com', phone: '+15555555555', externalId: '1029f9v9sjd0as' })
269
+ const { authToken, enduser } = await sdk.api.endusers.generate_auth_token({ id: e.id })
270
+ assert(!!authToken && !!enduser, 'invalid returned values', 'Generate authToken and get enduser')
271
+
272
+ const { isAuthenticated } = await sdk.api.endusers.is_authenticated({ id: enduser.id, authToken })
239
273
  assert(isAuthenticated, 'invalid authToken generated for enduser', 'Generate authToken for enduser is valid')
240
274
 
275
+ await async_test(
276
+ `auth by externalId`, () => sdk.api.endusers.generate_auth_token({ externalId: e.externalId }), passOnVoid,
277
+ )
278
+ await async_test(
279
+ `auth by email`, () => sdk.api.endusers.generate_auth_token({ email: e.email }), passOnVoid,
280
+ )
281
+ await async_test(
282
+ `auth by phone`, () => sdk.api.endusers.generate_auth_token({ phone: e.phone }), passOnVoid,
283
+ )
284
+ await async_test(
285
+ `auth by nothing throws error`, () => sdk.api.endusers.generate_auth_token({ phone: undefined }),
286
+ { shouldError: true, onError: e => e.message === "One of id, externalId, email, or phone is required" },
287
+ )
288
+ await async_test(
289
+ `auth by bad field throws error`, () => sdk.api.endusers.generate_auth_token({ email: "notavalidemail@tellescope.com" }),
290
+ { shouldError: true, onError: e => e.message === "Could not find a corresponding enduser" },
291
+ )
292
+
241
293
  await sdk.api.endusers.deleteOne(enduser.id)
242
294
  }
243
295
 
@@ -608,7 +660,7 @@ const journey_tests = async (queries=sdk.api.journeys) => {
608
660
 
609
661
  await async_test(
610
662
  `journey-updateState`,
611
- () => queries.updateState({ id: journey.id, name: 'Added', updates: { name: 'Updated', priority: 'N/A' }}),
663
+ () => queries.update_state({ id: journey.id, name: 'Added', updates: { name: 'Updated', priority: 'N/A' }}),
612
664
  passOnVoid,
613
665
  )
614
666
  await wait(undefined, 25) // wait for side effects to update endusers
@@ -894,7 +946,7 @@ const enduserAccessTests = async () => {
894
946
  const password = 'testpassword'
895
947
 
896
948
  const enduser = await sdk.api.endusers.createOne({ email })
897
- await sdk.api.endusers.setPassword({ id: enduser.id, password }).catch(console.error)
949
+ await sdk.api.endusers.set_password({ id: enduser.id, password }).catch(console.error)
898
950
  await enduserSDK.authenticate(email, password).catch(console.error)
899
951
 
900
952
  for (const n in schema) {
@@ -973,6 +1025,20 @@ const enduserAccessTests = async () => {
973
1025
  await sdk.api.endusers.deleteOne(enduser.id)
974
1026
  }
975
1027
 
1028
+ const files_tests = async () => {
1029
+ const buff = buffer.Buffer.from('test file data')
1030
+
1031
+ const { presignedUpload, file } = await sdk.api.files.prepare_file_upload({
1032
+ name: 'Test File', size: buff.byteLength, type: 'text/plain'
1033
+ })
1034
+ await sdk.UPLOAD(presignedUpload, undefined, buff as any)
1035
+
1036
+ const { downloadURL } = await sdk.api.files.file_download_URL({ secureName: file.secureName })
1037
+ const downloaded: string = await sdk.DOWNLOAD(downloadURL)
1038
+
1039
+ assert(downloaded === buff.toString(), 'downloaded file does not match uploaded file', 'upload, download comparison')
1040
+ }
1041
+
976
1042
  const tests: { [K in keyof ClientModelForName]: () => void } = {
977
1043
  chats: chat_tests,
978
1044
  endusers: enduser_tests,
@@ -985,9 +1051,10 @@ const tests: { [K in keyof ClientModelForName]: () => void } = {
985
1051
  chat_rooms: chat_room_tests,
986
1052
  users: () => {},
987
1053
  templates: () => {},
988
- files: () => {},
1054
+ files: files_tests,
989
1055
  tickets: () => {},
990
1056
  meetings: () => {},
1057
+ notes: () => {},
991
1058
  };
992
1059
 
993
1060
  (async () => {