@auxilium/datalynk-client 0.9.12 → 1.0.0

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/index.mjs CHANGED
@@ -32,6 +32,10 @@ function JSONSanitize(obj, space) {
32
32
  return value2;
33
33
  }, space);
34
34
  }
35
+ function flattenArr(arr, result = []) {
36
+ arr.forEach((el) => Array.isArray(el) ? flattenArr(el, result) : result.push(el));
37
+ return result;
38
+ }
35
39
  class PromiseProgress extends Promise {
36
40
  constructor(executor) {
37
41
  super((resolve, reject) => executor(
@@ -1675,7 +1679,7 @@ class Auth {
1675
1679
  * @return {Promise<boolean>} True if system administrator
1676
1680
  */
1677
1681
  async isSysAdmin() {
1678
- return !!(await this.api.slice("sysadmin").select().where("auth_ref", "==", "$viewer").exec().keys()).length;
1682
+ return !!(await this.api.slice("sysadmin").select().where("auth_ref", "==", "$viewer").rows().exec()).length;
1679
1683
  }
1680
1684
  /**
1681
1685
  * Check if user is a table administrator
@@ -1683,7 +1687,7 @@ class Auth {
1683
1687
  * @return {Promise<boolean>} True if table administrator
1684
1688
  */
1685
1689
  async isTableAdmin() {
1686
- return !!(await this.api.slice("tableadmins").select().where("auth_ref", "==", "$viewer").exec().keys()).length;
1690
+ return !!(await this.api.slice("tableadmins").select().where("auth_ref", "==", "$viewer").rows().exec()).length;
1687
1691
  }
1688
1692
  /**
1689
1693
  * Check if user is a user administrator
@@ -1691,7 +1695,7 @@ class Auth {
1691
1695
  * @return {Promise<boolean>} True if user administrator
1692
1696
  */
1693
1697
  async isUserAdmin() {
1694
- return !!(await this.api.slice("useradmins").select().where("auth_ref", "==", "$viewer").exec().keys()).length;
1698
+ return !!(await this.api.slice("useradmins").select().where("auth_ref", "==", "$viewer").rows().exec()).length;
1695
1699
  }
1696
1700
  /**
1697
1701
  * Perform login and save the session token
@@ -1832,7 +1836,7 @@ class Files {
1832
1836
  })).then(async (files2) => {
1833
1837
  if (associate) {
1834
1838
  let id = typeof associate.row == "number" ? associate.row : associate.row[associate.pk || "id"];
1835
- if (!id) id = await this.api.slice(associate.slice).insert(associate.row).exec().key();
1839
+ if (!id) id = await this.api.slice(associate.slice).insert(associate.row).id();
1836
1840
  await this.associate(files2.map((f2) => f2.id), associate == null ? void 0 : associate.slice, associate == null ? void 0 : associate.row, associate == null ? void 0 : associate.field);
1837
1841
  }
1838
1842
  return files2;
@@ -1992,112 +1996,6 @@ const Serializer = {
1992
1996
  }
1993
1997
  }
1994
1998
  };
1995
- class SlicePromise {
1996
- /**
1997
- * An object to provide helpers for Datalynk results
1998
- *
1999
- * @param slice
2000
- * @param {SliceResponse<T>} promise Datalynk promise to handle
2001
- */
2002
- constructor(slice, promise) {
2003
- this.slice = slice;
2004
- this.promise = promise;
2005
- }
2006
- /**
2007
- * Catch promise errors
2008
- */
2009
- catch(callback) {
2010
- return this.promise.catch(callback);
2011
- }
2012
- /**
2013
- * Count rows or fetch count alias result
2014
- */
2015
- async count() {
2016
- var _a, _b;
2017
- const rows = await this.rows();
2018
- if (typeof ((_a = rows == null ? void 0 : rows[0]) == null ? void 0 : _a["count"]) == "number") return (_b = rows == null ? void 0 : rows[0]) == null ? void 0 : _b["count"];
2019
- return rows.length;
2020
- }
2021
- /**
2022
- * Log the raw result to the console for inspection
2023
- */
2024
- debug() {
2025
- this.promise.then((resp) => console.log(resp));
2026
- return this;
2027
- }
2028
- /**
2029
- * Fields that failed
2030
- */
2031
- async failed() {
2032
- let resp = await this.promise;
2033
- return resp.failed;
2034
- }
2035
- /**
2036
- * Catch promise errors
2037
- */
2038
- finally(callback) {
2039
- return this.promise.finally(callback);
2040
- }
2041
- /**
2042
- * Fields that were ignored (Perms or readonly)
2043
- */
2044
- async ignored() {
2045
- let resp = await this.promise;
2046
- return resp["ignored-fields"];
2047
- }
2048
- /**
2049
- * ID of first affected row
2050
- */
2051
- async key() {
2052
- return (await this.keys())[0];
2053
- }
2054
- /**
2055
- * IDs of all affected rows
2056
- */
2057
- async keys() {
2058
- let resp = await this.promise;
2059
- return resp.keys;
2060
- }
2061
- /**
2062
- * Fields that were affected successfully
2063
- */
2064
- async granted() {
2065
- let resp = await this.promise;
2066
- return resp.granted;
2067
- }
2068
- /**
2069
- * First row of data
2070
- */
2071
- async row() {
2072
- return (await this.rows())[0];
2073
- }
2074
- /**
2075
- * All rows of data
2076
- */
2077
- async rows() {
2078
- let resp = await this.promise;
2079
- return resp.rows;
2080
- }
2081
- /**
2082
- * Handle as normal request
2083
- */
2084
- then(success, error) {
2085
- return this.promise.then(success, error);
2086
- }
2087
- /**
2088
- * Get the raw promise
2089
- */
2090
- toPromise() {
2091
- return this.promise;
2092
- }
2093
- /**
2094
- * Get the transaction ID
2095
- */
2096
- async transaction() {
2097
- let resp = await this.promise;
2098
- return resp.tx;
2099
- }
2100
- }
2101
1999
  const _Slice = class _Slice {
2102
2000
  /**
2103
2001
  * An object to aid in constructing requests
@@ -2107,11 +2005,25 @@ const _Slice = class _Slice {
2107
2005
  */
2108
2006
  constructor(slice, api) {
2109
2007
  __publicField(this, "operation");
2008
+ __publicField(this, "popField");
2110
2009
  __publicField(this, "request", {});
2010
+ /** Log response automatically */
2011
+ __publicField(this, "debugging");
2111
2012
  /** Unsubscribe from changes, undefined if not subscribed */
2112
2013
  __publicField(this, "unsubscribe");
2113
2014
  /** Cached slice data as an observable */
2114
2015
  __publicField(this, "cache$", new BehaviorSubject([]));
2016
+ /**
2017
+ * Whitelist and alias fields. Alias of `fields()`
2018
+ * @example
2019
+ * ```ts
2020
+ * const id: {id: number, field2: any}[] = await new Slice<T>(12345)
2021
+ * .select().alias({id: 'id', field1: 'field2'}).exec().keys();
2022
+ * ```
2023
+ * @param {object} aliasKeyVals List of properties to whitelist and what to rename them to
2024
+ * @return {Slice<T>}
2025
+ */
2026
+ __publicField(this, "alias", this.fields);
2115
2027
  this.slice = slice;
2116
2028
  this.api = api;
2117
2029
  }
@@ -2125,19 +2037,13 @@ const _Slice = class _Slice {
2125
2037
  }
2126
2038
  /** Get raw API request */
2127
2039
  get raw() {
2128
- return { [this.operation]: { slice: this.slice, ...this.request } };
2129
- }
2130
- /**
2131
- * Whitelist and alias fields. Alias for the fields functions
2132
- * @example
2133
- * ```ts
2134
- * const id: {id: number, field2: any}[] = await new Slice<T>(12345)
2135
- * .select().alias({id: 'id', field1: 'field2'}).exec().keys();
2136
- * ```
2137
- * @param {object} aliasKeyVals List of properties to whitelist and what to rename them to
2138
- */
2139
- alias(aliasKeyVals) {
2140
- return this.fields(aliasKeyVals);
2040
+ return clean({
2041
+ [this.operation]: {
2042
+ ...this.request,
2043
+ slice: this.slice
2044
+ },
2045
+ "$pop": this.popField ? this.popField : void 0
2046
+ });
2141
2047
  }
2142
2048
  /**
2143
2049
  * Add an 'AND' condition inside the where argument
@@ -2149,6 +2055,7 @@ const _Slice = class _Slice {
2149
2055
  * .where({field2: 2, field3: 3})
2150
2056
  * .exec().rows();
2151
2057
  * ```
2058
+ * @return {Slice<T>}
2152
2059
  */
2153
2060
  and() {
2154
2061
  var _a;
@@ -2166,17 +2073,20 @@ const _Slice = class _Slice {
2166
2073
  * .exec().count();
2167
2074
  * ```
2168
2075
  * @param {object | string} arg Count argument
2076
+ * @return {Slice<T>}
2169
2077
  */
2170
2078
  count(arg = "id") {
2171
2079
  this.operation = "$/slice/report";
2172
2080
  this.request.fields = { count: ["$count", typeof arg == "object" ? arg : ["$field", arg]] };
2173
- return this;
2081
+ return this.pop("rows:0:count");
2174
2082
  }
2175
2083
  /**
2176
2084
  * Output the formed request to the console for inspection
2085
+ * @param {boolean} enabled Enable/Disable console logging
2086
+ * @return {Slice<T>}
2177
2087
  */
2178
- debug() {
2179
- console.debug(this.request);
2088
+ debug(enabled = true) {
2089
+ this.debugging = enabled;
2180
2090
  return this;
2181
2091
  }
2182
2092
  /**
@@ -2186,6 +2096,7 @@ const _Slice = class _Slice {
2186
2096
  * await new Slice(12345).delete(id).exec();
2187
2097
  * ```
2188
2098
  * @param {number | number[]} id ID(s) to delete
2099
+ * @return {Slice<T>}
2189
2100
  */
2190
2101
  delete(id) {
2191
2102
  this.operation = "$/slice/delete";
@@ -2204,6 +2115,7 @@ const _Slice = class _Slice {
2204
2115
  * .exec().rows();
2205
2116
  * ```
2206
2117
  * @param formula Excel formula to use as where clause
2118
+ * @return {Slice<T>}
2207
2119
  */
2208
2120
  excel(formula) {
2209
2121
  this.where(["$excel", formula]);
@@ -2212,17 +2124,26 @@ const _Slice = class _Slice {
2212
2124
  /**
2213
2125
  * Compile the request and send it
2214
2126
  * @param {ApiRequestOptions} options API Request options
2215
- * @return {SlicePromise<T>}
2127
+ * @return {Promise<T = any>} API response
2216
2128
  */
2217
2129
  exec(options) {
2218
2130
  if (!this.operation) throw new Error("No operation chosen");
2219
- this.request.slice = this.slice;
2220
- return new SlicePromise(this, this.api.request({ [this.operation]: this.request }, options));
2131
+ return this.api.request(this.raw, options).then((resp) => {
2132
+ if (this.debugging) console.log(resp);
2133
+ return resp;
2134
+ });
2221
2135
  }
2222
2136
  fields(keys) {
2223
2137
  this.request.fields = Array.isArray(keys) ? keys.reduce((acc, key) => ({ ...acc, [key]: key }), {}) : keys;
2224
2138
  return this;
2225
2139
  }
2140
+ /**
2141
+ * Unwrap response returning the first ID
2142
+ * @return {Slice<T>}
2143
+ */
2144
+ id() {
2145
+ return this.pop("rows:0:id");
2146
+ }
2226
2147
  /**
2227
2148
  * Set the request type to insert
2228
2149
  * @example
@@ -2233,6 +2154,7 @@ const _Slice = class _Slice {
2233
2154
  * ]).exec().keys();
2234
2155
  * ```
2235
2156
  * @param {T | T[]} rows Rows to be inserted into the slice
2157
+ * @return {Slice<T>}
2236
2158
  */
2237
2159
  insert(rows) {
2238
2160
  this.operation = "$/slice/xinsert";
@@ -2249,9 +2171,11 @@ const _Slice = class _Slice {
2249
2171
  * .exec().rows();
2250
2172
  * ```
2251
2173
  * @param {number} num Number of rows to return
2174
+ * @return {Slice<T>}
2252
2175
  */
2253
2176
  limit(num) {
2254
2177
  this.request.limit = num;
2178
+ return this;
2255
2179
  }
2256
2180
  /**
2257
2181
  * Add an 'OR' condition inside the where argument
@@ -2265,6 +2189,7 @@ const _Slice = class _Slice {
2265
2189
  * .where(['$gt', ['$field', field4], 4)
2266
2190
  * .exec().rows();
2267
2191
  * ```
2192
+ * @return {Slice<T>}
2268
2193
  */
2269
2194
  or() {
2270
2195
  var _a;
@@ -2285,12 +2210,36 @@ const _Slice = class _Slice {
2285
2210
  * ```
2286
2211
  * @param {string} field property name
2287
2212
  * @param {boolean} ascending Sort in ascending or descending order
2213
+ * @return {Slice<T>}
2288
2214
  */
2289
2215
  order(field, ascending = true) {
2290
2216
  if (!this.request.order) this.request.order = [];
2291
2217
  this.request.order.push([ascending ? "$asc" : "$desc", ["$field", field]]);
2292
2218
  return this;
2293
2219
  }
2220
+ /**
2221
+ * Unwrap response, returning the field
2222
+ * @param {string} field Colon seperated path: `rows:0`
2223
+ * @return {Slice<T>}
2224
+ */
2225
+ pop(field) {
2226
+ this.popField = field;
2227
+ return this;
2228
+ }
2229
+ /**
2230
+ * Unwrap response returning the first row
2231
+ * @return {Slice<T>}
2232
+ */
2233
+ row() {
2234
+ return this.pop("rows:0");
2235
+ }
2236
+ /**
2237
+ * Unwrap response returning the rows
2238
+ * @return {Slice<T>}
2239
+ */
2240
+ rows() {
2241
+ return this.pop("rows");
2242
+ }
2294
2243
  /**
2295
2244
  * Set the request type to select
2296
2245
  * @example
@@ -2299,6 +2248,7 @@ const _Slice = class _Slice {
2299
2248
  * const row: T = new Slice<T>(12345).select(id).exec().row();
2300
2249
  * ```
2301
2250
  * @param {number | number[]} id ID(s) to select, leaving blank will return all rows
2251
+ * @return {Slice<T>}
2302
2252
  */
2303
2253
  select(id) {
2304
2254
  this.operation = "$/slice/report";
@@ -2320,10 +2270,10 @@ const _Slice = class _Slice {
2320
2270
  */
2321
2271
  sync(on = true) {
2322
2272
  if (on) {
2323
- new _Slice(this.slice, this.api).select().exec().rows().then((rows) => this.cache = rows);
2273
+ new _Slice(this.slice, this.api).select().rows().exec().then((rows) => this.cache = rows);
2324
2274
  if (!this.unsubscribe) this.unsubscribe = this.api.socket.sliceEvents(this.slice, (event) => {
2325
2275
  const ids = [...event.data.new, ...event.data.changed];
2326
- new _Slice(this.slice, this.api).select(ids).exec().rows().then((rows) => this.cache = [...this.cache.filter((c) => c.id != null && !ids.includes(c.id)), ...rows]);
2276
+ new _Slice(this.slice, this.api).select(ids).rows().exec().then((rows) => this.cache = [...this.cache.filter((c) => c.id != null && !ids.includes(c.id)), ...rows]);
2327
2277
  this.cache = this.cache.filter((v) => v.id && !event.data.lost.includes(v.id));
2328
2278
  });
2329
2279
  return this.cache$;
@@ -2342,6 +2292,7 @@ const _Slice = class _Slice {
2342
2292
  * ]).exec().keys();
2343
2293
  * ```
2344
2294
  * @param {T | T[]} rows Rows to be updated, each row must have an ID
2295
+ * @return {Slice<T>}
2345
2296
  */
2346
2297
  update(rows) {
2347
2298
  this.operation = "$/slice/xupdate";
@@ -2364,6 +2315,7 @@ const _Slice = class _Slice {
2364
2315
  * @param {string | object} field property to compare or a map of equality comparisons
2365
2316
  * @param {string} operator Operation to compare with. Accepts JS operators (>=, ==, !=, ...) as well as datalynk styax ($gte, $eq, $is, $not, ...)
2366
2317
  * @param {any} value value to compare against
2318
+ * @return {Slice<T>}
2367
2319
  */
2368
2320
  where(field, operator, value) {
2369
2321
  if (this.request.where && this.request.where[0] != "$or") this.and();
@@ -2552,9 +2504,8 @@ class Api {
2552
2504
  __publicField(this, "bundleOngoing", false);
2553
2505
  /** LocalStorage key for persisting logins */
2554
2506
  __publicField(this, "localStorageKey", "datalynk-token");
2555
- /** Pending requests */
2507
+ /** Pending requests cache */
2556
2508
  __publicField(this, "pending", {});
2557
- // Cache for ongoing requests
2558
2509
  /** Authentication helpers */
2559
2510
  __publicField(this, "auth", new Auth(this));
2560
2511
  /** File helpers */
@@ -2565,9 +2516,8 @@ class Api {
2565
2516
  __publicField(this, "socket");
2566
2517
  /** Superuser helpers */
2567
2518
  __publicField(this, "superuser", new Superuser(this));
2568
- /** API endpoint */
2519
+ /** API URL endpoint */
2569
2520
  __publicField(this, "url");
2570
- // API URL endpoint for requests
2571
2521
  /** API Session token */
2572
2522
  __publicField(this, "token$", new BehaviorSubject(null));
2573
2523
  this.options = options;
@@ -2647,10 +2597,10 @@ class Api {
2647
2597
  /**
2648
2598
  * Chain multiple requests to execute together
2649
2599
  * @param {Slice<any>} requests List of requests to chain
2650
- * @return {Promise<SlicePromise[]>} API Response
2600
+ * @return {Promise<any>} API Response
2651
2601
  */
2652
2602
  chain(...requests) {
2653
- return this.request({ "$/tools/action_chain": requests.flatMap((r) => r instanceof Slice ? r.raw : r) });
2603
+ return this.request({ "$/tools/action_chain": flattenArr(requests).map((r) => r instanceof Slice ? r.raw : r) });
2654
2604
  }
2655
2605
  /**
2656
2606
  * Organize multiple requests into a single mapped request
@@ -2659,11 +2609,27 @@ class Api {
2659
2609
  */
2660
2610
  chainMap(request) {
2661
2611
  return this.request({ "$/tools/do": [
2662
- ...Object.entries(request).flatMap(([key, r]) => [key, r instanceof Slice ? r.raw : r]),
2612
+ ...Object.entries(request).flatMap(([key, r]) => [key, r instanceof Slice ? r == null ? void 0 : r.raw : r]),
2663
2613
  "returnAllBoilerplate",
2664
2614
  { "$_": "*" }
2665
2615
  ] }, {});
2666
2616
  }
2617
+ /**
2618
+ * Exact same as `request` method, but logs the response in the console automatically
2619
+ *
2620
+ * @param {object | string} data Datalynk request as object or string
2621
+ * @param {ApiRequestOptions} options
2622
+ * @returns {Promise<any>} Datalynk response
2623
+ */
2624
+ debug(data, options = {}) {
2625
+ return this.request(data, options).then((data2) => {
2626
+ console.log(data2);
2627
+ return data2;
2628
+ }).catch((err) => {
2629
+ console.error(err);
2630
+ return err;
2631
+ });
2632
+ }
2667
2633
  /**
2668
2634
  * Send a request to Datalynk
2669
2635
  *
@@ -2678,7 +2644,7 @@ class Api {
2678
2644
  */
2679
2645
  request(data, options = {}) {
2680
2646
  data = typeof data == "string" ? { [data]: {} } : data;
2681
- if (options.force) {
2647
+ if (options.noOptimize) {
2682
2648
  return new Promise((res, rej) => {
2683
2649
  this._request(data, options).then((resp) => {
2684
2650
  (resp == null ? void 0 : resp.error) ? rej(resp) : res(resp);
@@ -2716,27 +2682,11 @@ class Api {
2716
2682
  * ```
2717
2683
  *
2718
2684
  * @param {number} slice Slice number the object will target
2719
- * @returns {Slice<T extends SliceMeta>} Object for making requests & caching rows
2685
+ * @returns {Slice<T = any>} Object for making requests & caching rows
2720
2686
  */
2721
2687
  slice(slice) {
2722
2688
  return new Slice(slice, this);
2723
2689
  }
2724
- /**
2725
- * Exact same as `request` method, but logs the response in the console automatically
2726
- *
2727
- * @param {object | string} data Datalynk request as object or string
2728
- * @param {ApiRequestOptions} options
2729
- * @returns {Promise<any>} Datalynk response
2730
- */
2731
- test(data, options = {}) {
2732
- return this.request(data, options).then((data2) => {
2733
- console.log(data2);
2734
- return data2;
2735
- }).catch((err) => {
2736
- console.error(err);
2737
- return err;
2738
- });
2739
- }
2740
2690
  }
2741
2691
  export {
2742
2692
  Api,
@@ -2746,7 +2696,6 @@ export {
2746
2696
  Pdf,
2747
2697
  Serializer,
2748
2698
  Slice,
2749
- SlicePromise,
2750
2699
  Socket,
2751
2700
  Superuser
2752
2701
  };