@auxilium/datalynk-client 1.0.15 → 1.0.16

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/dist/api.d.ts ADDED
@@ -0,0 +1,162 @@
1
+ import { BehaviorSubject } from 'rxjs';
2
+ import { Auth } from './auth';
3
+ import { Files } from './files';
4
+ import { Pdf } from './pdf';
5
+ import { Slice } from './slice';
6
+ import { Socket } from './socket';
7
+ import { Superuser } from './superuser';
8
+ export type JwtPayload = {
9
+ aud: string;
10
+ email: string;
11
+ exp: number;
12
+ iat: number;
13
+ iss: string;
14
+ jti: string;
15
+ payload: any;
16
+ realm: string;
17
+ timezone: string;
18
+ uid: number;
19
+ };
20
+ /**
21
+ * Api connection options
22
+ */
23
+ export type ApiOptions = {
24
+ /** Bundle requests together that happen in quick succession */
25
+ bundleTime?: number;
26
+ /** Use legacy dates by default */
27
+ legacyDates?: boolean;
28
+ /** Name of client for logging */
29
+ origin?: string;
30
+ /** Save session token to localStorage to persist logins */
31
+ saveSession?: boolean;
32
+ /** Disable sockets with false or override socket URL */
33
+ socket?: false | string;
34
+ };
35
+ /**
36
+ * Possible options for API calls
37
+ */
38
+ export interface ApiRequestOptions {
39
+ /** Skip bundling & caching */
40
+ noOptimize?: boolean;
41
+ /** Skip the token translating step */
42
+ raw?: boolean;
43
+ /** Set request token */
44
+ token?: string;
45
+ }
46
+ /** API error response */
47
+ export interface ApiError {
48
+ /** Error message */
49
+ message: string;
50
+ /** Source of error */
51
+ request: any;
52
+ /** Extra debugging information */
53
+ debug?: any;
54
+ /** Stack trace */
55
+ trace?: any;
56
+ }
57
+ /**
58
+ * Connect to Datalynk & send requests
59
+ */
60
+ export declare class Api {
61
+ readonly options: ApiOptions;
62
+ /** Current requests bundle */
63
+ private bundle;
64
+ /** Bundle lifecycle tracking */
65
+ private bundleOngoing;
66
+ /** LocalStorage key for persisting logins */
67
+ private localStorageKey;
68
+ /** Pending requests cache */
69
+ private pending;
70
+ /** API URL */
71
+ readonly url: string;
72
+ /** Package version */
73
+ version: string;
74
+ /** API Session token */
75
+ token$: BehaviorSubject<string | null>;
76
+ get token(): string | null;
77
+ set token(token: string | null);
78
+ /** Get session info from JWT payload */
79
+ get jwtPayload(): JwtPayload | null;
80
+ /** Helpers */
81
+ /** Authentication */
82
+ readonly auth: Auth;
83
+ /** File */
84
+ readonly files: Files;
85
+ /** PDF */
86
+ readonly pdf: Pdf;
87
+ /** Socket */
88
+ readonly socket: Socket;
89
+ /** Superuser */
90
+ readonly superuser: Superuser;
91
+ /**
92
+ * Connect to Datalynk & send requests
93
+ *
94
+ * @example
95
+ * ```ts
96
+ * const api = new Api('https://spoke.auxiliumgroup.com');
97
+ * ```
98
+ *
99
+ * @param {string} url API URL
100
+ * @param {ApiOptions} options
101
+ */
102
+ constructor(url: string, options?: ApiOptions);
103
+ private _request;
104
+ /**
105
+ * Parses API request/response object for special Datalynk tokens & converts them to native JS objects
106
+ *
107
+ * @param obj An API request or response
108
+ * @return {Object} Api request or response with translated tokens
109
+ * @private
110
+ */
111
+ private static translateTokens;
112
+ /**
113
+ * Chain multiple requests to execute together
114
+ * @param {Slice<any>} requests List of requests to chain
115
+ * @return {Promise<any>} API Response
116
+ */
117
+ chain(...requests: (any | Slice<any>)[]): Promise<any>;
118
+ /**
119
+ * Organize multiple requests into a single mapped request
120
+ * @param {{[p: string]: any}} request Map of requests
121
+ * @return {Promise<any>} Map of API Responses
122
+ */
123
+ chainMap(request: {
124
+ [key: string]: any;
125
+ }): Promise<any>;
126
+ /**
127
+ * Exact same as `request` method, but logs the response in the console automatically
128
+ *
129
+ * @param {object | string} data Datalynk request as object or string
130
+ * @param {ApiRequestOptions} options
131
+ * @returns {Promise<any>} Datalynk response
132
+ */
133
+ debug<T = any>(data: any, options?: ApiRequestOptions): Promise<T>;
134
+ /**
135
+ * Send a request to Datalynk
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * const response = await api.request('$/auth/current');
140
+ * ```
141
+ *
142
+ * @param {object} data Request using Datalynk API syntax. Strings will be converted: '$/auth/current' -> {'$/auth/current': {}}
143
+ * @param {ApiRequestOptions} options
144
+ * @returns {Promise<any>} Datalynk response or error
145
+ */
146
+ request<T = any>(data: any, options?: ApiRequestOptions): Promise<T>;
147
+ /**
148
+ * Create a slice object using the API
149
+ *
150
+ * @example
151
+ * ```ts
152
+ * const contactsSlice = api.slice<Contacts>(12345);
153
+ * const allContacts = await contactsSlice.select().exec().rows();
154
+ * const unsubscribe = contactsSlice.sync().subscribe(rows => console.log(rows));
155
+ * ```
156
+ *
157
+ * @param {number} slice Slice number the object will target
158
+ * @returns {Slice<T = any>} Object for making requests & caching rows
159
+ */
160
+ slice<T = any>(slice: number | string): Slice<T>;
161
+ }
162
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
package/dist/auth.d.ts ADDED
@@ -0,0 +1,141 @@
1
+ import { BehaviorSubject } from 'rxjs';
2
+ import { Api } from './api';
3
+ import { LoginPrompt, LoginPromptOptions } from './login-prompt';
4
+ /** User Account */
5
+ export type User = {
6
+ /** User ID */
7
+ id: Number;
8
+ /** Current session token */
9
+ token: string;
10
+ /** Whether account is considered a guest */
11
+ guest: boolean;
12
+ /** Whether account is an admin */
13
+ sysadmin: boolean;
14
+ /** Account holders firstname */
15
+ first_name: string;
16
+ /** Account holders lastname */
17
+ last_name: string;
18
+ /** Contact email address */
19
+ email: string;
20
+ /** Username for logging in */
21
+ login: string;
22
+ "2FA"?: string;
23
+ "2FA_code"?: string;
24
+ /** Contact phone number */
25
+ mobile_phone?: string;
26
+ /** Spoke user comes from */
27
+ spoke: string;
28
+ };
29
+ /**
30
+ * Authentication requests
31
+ */
32
+ export declare class Auth {
33
+ private readonly api;
34
+ /** Current user as an observable */
35
+ user$: BehaviorSubject<User | null | undefined>;
36
+ /** Current user */
37
+ get user(): User | null | undefined;
38
+ /** Set current user info */
39
+ set user(user: User | null | undefined);
40
+ get spoke(): string | null;
41
+ constructor(api: Api);
42
+ /**
43
+ * Get current user associated with API token
44
+ *
45
+ * @return {Promise<User | null>}
46
+ */
47
+ current(token?: string | null): Promise<null | User>;
48
+ /**
49
+ * Automatically handle sessions by checking localStorage & URL parameters for a token & prompting
50
+ * user with a login screen if required
51
+ *
52
+ * @param {string} spoke Desired spoke
53
+ * @param {LoginPromptOptions} options Aesthetic options
54
+ * @return {Promise<void>} Login complete
55
+ */
56
+ handleLogin(spoke: string, options?: LoginPromptOptions): Promise<void>;
57
+ /**
58
+ * Check whether user has a token
59
+ *
60
+ * @return {boolean} True if session token authenticated
61
+ */
62
+ isAuthenticated(): boolean;
63
+ /**
64
+ * Check if the current user is a guest
65
+ *
66
+ * @return {boolean} True if guest
67
+ */
68
+ isGuest(): boolean;
69
+ /**
70
+ * Check if user is a system administrator
71
+ *
72
+ * @return {Promise<boolean>} True if system administrator
73
+ */
74
+ isSysAdmin(): Promise<boolean>;
75
+ /**
76
+ * Check if user is a table administrator
77
+ *
78
+ * @return {Promise<boolean>} True if table administrator
79
+ */
80
+ isTableAdmin(): Promise<boolean>;
81
+ /**
82
+ * Check if user is a user administrator
83
+ *
84
+ * @return {Promise<boolean>} True if user administrator
85
+ */
86
+ isUserAdmin(): Promise<boolean>;
87
+ /**
88
+ * Perform login and save the session token
89
+ *
90
+ * @param {string} login Login username or email
91
+ * @param {string} password Password for account
92
+ * @param {string} spoke Override login spoke
93
+ * @param {twoFactor?: string, expire?: string} opts 2FA code & expire date (YYYY-MM-DD)
94
+ * @returns {Promise<User>} User account
95
+ */
96
+ login(spoke: string, login: string, password: string, opts?: {
97
+ twoFactor?: string;
98
+ expire?: null | string;
99
+ }): Promise<User>;
100
+ /**
101
+ * Login as guest user
102
+ *
103
+ * @return {Promise<User>} Guest account
104
+ */
105
+ loginGuest(): Promise<User>;
106
+ /**
107
+ * Create Login UI
108
+ *
109
+ * @param {string} spoke Desired spoke
110
+ * @param {LoginPromptOptions} options Aesthetic options
111
+ * @return {LoginPrompt} Login prompt
112
+ */
113
+ loginPrompt(spoke: string, options?: LoginPromptOptions): LoginPrompt;
114
+ /**
115
+ * Logout current user
116
+ *
117
+ * @return {Promise<{closed: string, new: string}>}
118
+ */
119
+ logout(): Promise<{
120
+ closed: string;
121
+ new: string;
122
+ }>;
123
+ /**
124
+ * Reset user account password
125
+ *
126
+ * @param {string} login User login
127
+ * @param {string} newPassword New password
128
+ * @param {string} code Reset code sent with `resetRequest`
129
+ * @return {Promise<any>} New session
130
+ */
131
+ reset(login: string, newPassword: string, code?: string): Promise<any>;
132
+ /**
133
+ * Request reset code for user
134
+ *
135
+ * @param {string} login User to reset
136
+ * @param {"email" | "sms" | "voice"} mode Method of sending reset code
137
+ * @return {Promise<any>} Unknown
138
+ */
139
+ resetRequest(login: string, mode: 'email' | 'sms' | 'voice'): Promise<any>;
140
+ }
141
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAyB,MAAM,MAAM,CAAC;AAC7D,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAC,WAAW,EAAE,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AAE/D,mBAAmB;AACnB,MAAM,MAAM,IAAI,GAAG;IAClB,cAAc;IACd,EAAE,EAAE,MAAM,CAAC;IACX,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,KAAK,EAAE,OAAO,CAAC;IACf,kCAAkC;IAClC,QAAQ,EAAE,OAAO,CAAC;IAClB,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2BAA2B;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;CACd,CAAA;AAED;;GAEG;AACH,qBAAa,IAAI;IAUJ,OAAO,CAAC,QAAQ,CAAC,GAAG;IAThC,oCAAoC;IACpC,KAAK,2CAA2D;IAChE,mBAAmB;IACnB,IAAI,IAAI,IAEO,IAAI,GAAG,IAAI,GAAG,SAAS,CAFM;IAC5C,4BAA4B;IAC5B,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,EAA4B;IAElE,IAAI,KAAK,kBAAiD;gBAE7B,GAAG,EAAE,GAAG;IAOrC;;;;OAIG;IACG,OAAO,CAAC,KAAK,GAAE,MAAM,GAAG,IAA0B,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAM/E;;;;;;;OAOG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB7E;;;;OAIG;IACH,eAAe;IAEf;;;;OAIG;IACH,OAAO;IAEP;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAOpC;;;;OAIG;IACG,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC;IAOtC;;;;OAIG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAOrC;;;;;;;;OAQG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,IAAI,GAAG,MAAM,CAAA;KAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBzH;;;;OAIG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B;;;;;;OAMG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,WAAW;IAIrE;;;;OAIG;IACH,MAAM;gBAC6B,MAAM;aAAO,MAAM;;IAMtD;;;;;;;OAOG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;IAWvD;;;;;;OAMG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,KAAK,GAAG,OAAO;CAI3D"}
@@ -0,0 +1,66 @@
1
+ import { Api } from './api';
2
+ /**
3
+ * Metadata for an uploaded file in Datalynk
4
+ */
5
+ export interface UploadedFile {
6
+ /** File ID used to reference file in Datalynk */
7
+ id: number;
8
+ /** Filename */
9
+ name: string;
10
+ /** Size of file on disk */
11
+ size: number;
12
+ /** Filename extension */
13
+ extension: string;
14
+ /** Mimetype */
15
+ mime: string;
16
+ /** URL to open file */
17
+ url?: string;
18
+ }
19
+ /**
20
+ * Handle uploading & fetching files from Datalynk
21
+ */
22
+ export declare class Files {
23
+ private readonly api;
24
+ readonly url: string;
25
+ constructor(api: Api);
26
+ /**
27
+ * Associate an existing file with an existing row
28
+ *
29
+ * @param {number | number[]} fileIds Existing files to associate
30
+ * @param {number} slice Target slice
31
+ * @param {number} row Target slice record
32
+ * @param {string} field Record filed file should be added to
33
+ * @param {boolean} execute Will run request by default, passing false will return the API request instead
34
+ * @return {any} The API response by default, or the raw API request if execute is false
35
+ */
36
+ associate(fileIds: number | number[], slice: number, row: number, field: string, execute?: true): Promise<any>;
37
+ associate(fileIds: number | number[], slice: number, row: number, field: string, execute: false): {
38
+ '!/tools/file/update': {
39
+ slice: number;
40
+ row: number;
41
+ field: string;
42
+ ids: number[];
43
+ };
44
+ };
45
+ /**
46
+ * Get an authenticated URL to fetch files from
47
+ *
48
+ * @param {number} id File ID
49
+ * @param {boolean} ignoreToken Ignore authentication
50
+ * @return {string} URL file can be viewed at
51
+ */
52
+ get(id: number, ignoreToken?: boolean): string;
53
+ /**
54
+ * Upload file(s) to the API & optionally associate them with a row
55
+ *
56
+ * @param {FileList | File | File[]} files Files to be uploaded
57
+ * @param {{slice: number, row: any, field: string, pk?: string}} associate Row to associate with
58
+ */
59
+ upload(files: FileList | File | File[], associate?: {
60
+ slice: number;
61
+ row: number | any;
62
+ field: string;
63
+ pk?: string;
64
+ }): Promise<UploadedFile[]>;
65
+ }
66
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../src/files.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,GAAG,EAAC,MAAM,OAAO,CAAC;AAE1B;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,iDAAiD;IACjD,EAAE,EAAE,MAAM,CAAC;IACX,eAAe;IACf,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe;IACf,IAAI,EAAE,MAAM,CAAC;IACb,uBAAuB;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,qBAAa,KAAK;IAGL,OAAO,CAAC,QAAQ,CAAC,GAAG;IAFhC,QAAQ,CAAC,GAAG,EAAG,MAAM,CAAA;gBAEQ,GAAG,EAAE,GAAG;IAIrC;;;;;;;;;OASG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC;IAC9G,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,GAAG;QAAC,qBAAqB,EAAE;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,EAAE,CAAA;SAAC,CAAA;KAAC;IAOrL;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM;IAI9C;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,GAAG,IAAI,EAAE,EAAE,SAAS,CAAC,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAC,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAyB5I"}