sfobjects-basic-client 1.1.4 → 1.1.5

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.d.ts CHANGED
@@ -133,6 +133,11 @@ export type SfDmlOptions = {
133
133
  };
134
134
  };
135
135
  };
136
+ export type SfClientOptions = {
137
+ breakOnError?: boolean;
138
+ query?: SfQueryOptions;
139
+ dml?: SfDmlOptions;
140
+ };
136
141
  export type SfQueryResult<R> = {
137
142
  records: R[];
138
143
  };
@@ -168,6 +173,7 @@ export interface SfWhereActions<OI, N extends KeyOf<OI>, S extends SfRootSelect<
168
173
  }
169
174
  export interface SfSelectAditionalActions<OI, N extends KeyOf<OI>, S extends SfRootSelect<OI, N>> {
170
175
  find: (id: string, options?: SfQueryOptions) => Promise<SfRootSelectProjection<OI, N, S> | undefined>;
176
+ retrieve: (id: string, options?: SfQueryOptions) => Promise<SfRootSelectProjection<OI, N, S>>;
171
177
  selection: S[];
172
178
  }
173
179
  export interface SfObjActions<OI, N extends KeyOf<OI>> {
@@ -183,10 +189,14 @@ export interface SfObjActions<OI, N extends KeyOf<OI>> {
183
189
  upsert: <K extends MandatoryCreateProps<OI[N]>>(records: SfUpsert<OI[N], K>[], key: K, options?: SfDmlOptions) => PromiseLike<SfSaveResult[]>;
184
190
  select: <S extends SfRootSelect<OI, N>>(select: S[]) => (SfSelectActions<OI, N, S> & SfWhereActions<OI, N, S> & SfSelectAditionalActions<OI, N, S>);
185
191
  }
192
+ export declare class SfBasicClientError extends Error {
193
+ errors: SfSaveError[];
194
+ constructor(errors: SfSaveError[]);
195
+ }
186
196
  export declare function isPlainObject(value: unknown): value is Record<string, any>;
187
197
  export declare function constructSoql<OI>(_cfg: SfObjCfgIndex<OI>): (objName: string, from: string, select: (string | {})[], where?: string | Record<string, any>, orderBy?: Record<string, any>, limit?: number) => string;
188
- export declare function getSfObject<OI>(_cfg: SfObjCfgIndex<OI>): <N extends KeyOf<OI>>(from: N, _conn: ISfConnection) => SfObjActions<OI, N>;
189
- export declare const getSfObjects: <OI>(cfg: SfObjCfgIndex<OI>) => (conn: ISfConnection) => { [N in KeyOf<OI>]: SfObjActions<OI, N>; };
198
+ export declare function getSfObject<OI>(_cfg: SfObjCfgIndex<OI>, o?: SfClientOptions): <N extends KeyOf<OI>>(from: N, _conn: ISfConnection) => SfObjActions<OI, N>;
199
+ export declare const getSfObjects: <OI>(cfg: SfObjCfgIndex<OI>) => (conn: ISfConnection, options?: SfClientOptions) => { [N in KeyOf<OI>]: SfObjActions<OI, N>; };
190
200
  export declare const sfObject: <OI, N extends KeyOf<OI>>(cfg: SfObjCfgIndex<OI>, n: N) => {
191
201
  info: SfObjCfgIndex<OI>[N];
192
202
  select: <S extends SfRootSelect<OI, N>>(s: S[]) => S[];
package/dist/index.js CHANGED
@@ -21,7 +21,7 @@ var __rest = (this && this.__rest) || function (s, e) {
21
21
  return t;
22
22
  };
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
- exports.sfObject = exports.getSfObjects = void 0;
24
+ exports.sfObject = exports.getSfObjects = exports.SfBasicClientError = void 0;
25
25
  exports.isPlainObject = isPlainObject;
26
26
  exports.constructSoql = constructSoql;
27
27
  exports.getSfObject = getSfObject;
@@ -70,6 +70,15 @@ const OP_RULES = [
70
70
  { ops: OP_KEYS_LIKE, soqlOp: 'like' },
71
71
  { ops: OP_KEYS_NLIKE, soqlOp: 'like', isNot: true },
72
72
  ];
73
+ class SfBasicClientError extends Error {
74
+ constructor(errors) {
75
+ super('Salesforce error(s): ' + errors.map(e => { var _a; return `[${e.errorCode}] ${e.message}, field(s): ${(_a = e.fields) === null || _a === void 0 ? void 0 : _a.join(',')}`; }).join(';\r\n'));
76
+ this.errors = errors;
77
+ this.name = 'SfBasicClientError';
78
+ Object.setPrototypeOf(this, new.target.prototype);
79
+ }
80
+ }
81
+ exports.SfBasicClientError = SfBasicClientError;
73
82
  // functions
74
83
  function isPlainObject(value) {
75
84
  if (typeof value !== 'object' || value === null)
@@ -222,36 +231,54 @@ function constructSoql(_cfg) {
222
231
  }
223
232
  return _constructFullQuery;
224
233
  }
225
- function getSfObject(_cfg) {
234
+ function processSaveResult(sr, breakOnError) {
235
+ if (breakOnError) {
236
+ const _errors = sr.filter(r => (r.success !== true)).map(r => r.errors).flat();
237
+ if (_errors.length) {
238
+ throw new SfBasicClientError(_errors);
239
+ }
240
+ }
241
+ return sr;
242
+ }
243
+ function getSfObject(_cfg, o) {
226
244
  function _query(conn, from, select, where, orderBy, limit) {
227
245
  const soql = () => constructSoql(_cfg)(from, from, select, where, orderBy, limit);
228
246
  return ({
229
247
  soql,
230
- get: (options) => __awaiter(this, void 0, void 0, function* () { return yield conn.query(soql(), options); }), // to get rid of promiselike,
248
+ get: (...args_1) => __awaiter(this, [...args_1], void 0, function* (options = o === null || o === void 0 ? void 0 : o.query) { return yield conn.query(soql(), options); }), // to get rid of promiselike,
231
249
  limit: (limit) => _query(conn, from, select, where, orderBy, limit)
232
250
  });
233
251
  }
252
+ function _queryOne(conn, from, select, id, options = o === null || o === void 0 ? void 0 : o.query) {
253
+ return _query(conn, from, select, `Id = '${id}'`).limit(1).get(options);
254
+ }
234
255
  return (from, _conn) => {
235
256
  return ({
236
257
  query: (q) => {
237
258
  const { select, where, orderBy, limit } = q;
238
259
  return _query(_conn, from, select, where, orderBy, limit);
239
260
  },
240
- delete: (ids, options) => _conn.delete(from, ids, options),
241
- update: (records, options) => _conn.update(from, records, options),
242
- create: (records, options) => _conn.create(from, records, options),
243
- upsert: (records, key, options) => _conn.upsert(from, records, key, options),
244
- select: (select) => (Object.assign(Object.assign({}, _query(_conn, from, select)), { orderBy: (orderBy) => _query(_conn, from, select, undefined, orderBy), where: (where) => (Object.assign(Object.assign({}, _query(_conn, from, select, where)), { orderBy: (orderBy) => _query(_conn, from, select, where, orderBy) })), find: (id, options) => __awaiter(this, void 0, void 0, function* () {
245
- const result = yield _query(_conn, from, select, `Id = '${id}'`).limit(1).get(options);
261
+ delete: (ids_1, ...args_1) => __awaiter(this, [ids_1, ...args_1], void 0, function* (ids, options = o === null || o === void 0 ? void 0 : o.dml) { return processSaveResult(yield _conn.delete(from, ids, options), o === null || o === void 0 ? void 0 : o.breakOnError); }),
262
+ update: (records_1, ...args_1) => __awaiter(this, [records_1, ...args_1], void 0, function* (records, options = o === null || o === void 0 ? void 0 : o.dml) { return processSaveResult(yield _conn.update(from, records, options), o === null || o === void 0 ? void 0 : o.breakOnError); }),
263
+ create: (records_1, ...args_1) => __awaiter(this, [records_1, ...args_1], void 0, function* (records, options = o === null || o === void 0 ? void 0 : o.dml) { return processSaveResult(yield _conn.create(from, records, options), o === null || o === void 0 ? void 0 : o.breakOnError); }),
264
+ upsert: (records_1, key_1, ...args_1) => __awaiter(this, [records_1, key_1, ...args_1], void 0, function* (records, key, options = o === null || o === void 0 ? void 0 : o.dml) { return processSaveResult(yield _conn.upsert(from, records, key, options), o === null || o === void 0 ? void 0 : o.breakOnError); }),
265
+ select: (select) => (Object.assign(Object.assign({}, _query(_conn, from, select)), { orderBy: (orderBy) => _query(_conn, from, select, undefined, orderBy), where: (where) => (Object.assign(Object.assign({}, _query(_conn, from, select, where)), { orderBy: (orderBy) => _query(_conn, from, select, where, orderBy) })), find: (id_1, ...args_1) => __awaiter(this, [id_1, ...args_1], void 0, function* (id, options = o === null || o === void 0 ? void 0 : o.query) {
266
+ const result = yield _queryOne(_conn, from, select, id, options);
246
267
  if (result.records.length) {
247
268
  return result.records[0];
248
269
  }
270
+ }), retrieve: (id_1, ...args_1) => __awaiter(this, [id_1, ...args_1], void 0, function* (id, options = o === null || o === void 0 ? void 0 : o.query) {
271
+ const result = yield _queryOne(_conn, from, select, id, options);
272
+ if (!result.records.length) {
273
+ throw new Error(`Record with id '${id}' is not found in '${from}'.`);
274
+ }
275
+ return result.records[0];
249
276
  }), selection: select }))
250
277
  });
251
278
  };
252
279
  }
253
- const getSfObjects = (cfg) => (conn) => {
254
- const _func = getSfObject(cfg);
280
+ const getSfObjects = (cfg) => (conn, options) => {
281
+ const _func = getSfObject(cfg, options);
255
282
  return Object.keys(cfg).reduce((p, n) => (Object.assign(Object.assign({}, p), { [n]: _func(n, conn) })), {});
256
283
  };
257
284
  exports.getSfObjects = getSfObjects;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sfobjects-basic-client",
3
- "version": "1.1.4",
3
+ "version": "1.1.5",
4
4
  "description": "Basic Salesforce Client to use together with sfobjects-to-typescript lib",
5
5
  "license": "ISC",
6
6
  "author": "Murad Aliyev",
package/src/index.ts CHANGED
@@ -228,6 +228,12 @@ export type SfDmlOptions = {
228
228
  };
229
229
  };
230
230
 
231
+ export type SfClientOptions = {
232
+ breakOnError?: boolean
233
+ query?: SfQueryOptions;
234
+ dml?: SfDmlOptions;
235
+ }
236
+
231
237
  export type SfQueryResult<R> = { records: R[] };
232
238
 
233
239
  export type SfSaveResult = {
@@ -268,6 +274,7 @@ export interface SfWhereActions<OI, N extends KeyOf<OI>, S extends SfRootSelect<
268
274
 
269
275
  export interface SfSelectAditionalActions<OI, N extends KeyOf<OI>, S extends SfRootSelect<OI, N>> {
270
276
  find: (id: string, options?: SfQueryOptions) => Promise<SfRootSelectProjection<OI, N, S> | undefined>;
277
+ retrieve: (id: string, options?: SfQueryOptions) => Promise<SfRootSelectProjection<OI, N, S>>;
271
278
  selection: S[];
272
279
  //S extends SfRootSelect<OI, N>
273
280
  }
@@ -281,6 +288,22 @@ export interface SfObjActions<OI, N extends KeyOf<OI>> {
281
288
  select: <S extends SfRootSelect<OI, N>>(select: S[]) => (SfSelectActions<OI, N, S> & SfWhereActions<OI, N, S> & SfSelectAditionalActions<OI, N, S>);
282
289
  }
283
290
 
291
+ export class SfBasicClientSaveError extends Error {
292
+ constructor(public errors: SfSaveError[]) {
293
+ super('Salesforce error(s): ' + errors.map(e => `[${e.errorCode}] ${e.message}, field(s): ${e.fields?.join(',')}`).join(';\r\n'))
294
+ this.name = 'SfBasicClientSaveError';
295
+ Object.setPrototypeOf(this, new.target.prototype);
296
+ }
297
+ }
298
+
299
+ export class SfBasicClientReadError extends Error {
300
+ constructor(public error: string) {
301
+ super('Salesforce error: ' + error)
302
+ this.name = 'SfBasicClientReadError';
303
+ Object.setPrototypeOf(this, new.target.prototype);
304
+ }
305
+ }
306
+
284
307
  // functions
285
308
 
286
309
  export function isPlainObject(value: unknown): value is Record<string, any> {
@@ -350,8 +373,6 @@ export function constructSoql<OI>(_cfg: SfObjCfgIndex<OI>) {
350
373
  'limit': limit?.toString()
351
374
  }
352
375
 
353
-
354
-
355
376
  return Object.keys(o).filter(k => !!o[k]).reduce((p, k) => ([p, k, o[k]].join(' ')), '');
356
377
  }
357
378
 
@@ -519,7 +540,22 @@ export function constructSoql<OI>(_cfg: SfObjCfgIndex<OI>) {
519
540
  return _constructFullQuery;
520
541
  }
521
542
 
522
- export function getSfObject<OI>(_cfg: SfObjCfgIndex<OI>) {
543
+ function processSaveResult(sr: SfSaveResult[], breakOnError?: boolean): SfSaveResult[] {
544
+
545
+ if (breakOnError) {
546
+
547
+ const _errors: SfSaveError[] = sr.filter(r => (r.success !== true)).map(r => r.errors).flat();
548
+
549
+ if (_errors.length) {
550
+ throw new SfBasicClientSaveError(_errors);
551
+ }
552
+ }
553
+
554
+ return sr;
555
+ }
556
+
557
+ export function getSfObject<OI>(_cfg: SfObjCfgIndex<OI>, o?: SfClientOptions) {
558
+
523
559
 
524
560
  function _query<S extends SfRootSelect<OI, N>, N extends KeyOf<OI>>(
525
561
  conn: ISfConnection,
@@ -534,11 +570,21 @@ export function getSfObject<OI>(_cfg: SfObjCfgIndex<OI>) {
534
570
 
535
571
  return ({
536
572
  soql,
537
- get: async (options?: SfQueryOptions) => await conn.query<SfRootSelectProjection<OI, N, S>>(soql(), options), // to get rid of promiselike,
573
+ get: async (options: SfQueryOptions | undefined = o?.query) => await conn.query<SfRootSelectProjection<OI, N, S>>(soql(), options), // to get rid of promiselike,
538
574
  limit: (limit: number) => _query(conn, from, select, where, orderBy, limit)
539
575
  });
540
576
  }
541
577
 
578
+ function _queryOne<S extends SfRootSelect<OI, N>, N extends KeyOf<OI>>(
579
+ conn: ISfConnection,
580
+ from: N,
581
+ select: S[],
582
+ id: string,
583
+ options: SfQueryOptions | undefined = o?.query
584
+ ) {
585
+ return _query(conn, from, select, `Id = '${id}'`).limit(1).get(options);
586
+ }
587
+
542
588
  return <N extends KeyOf<OI>>(from: N, _conn: ISfConnection): SfObjActions<OI, N> => {
543
589
 
544
590
  return ({
@@ -548,13 +594,13 @@ export function getSfObject<OI>(_cfg: SfObjCfgIndex<OI>) {
548
594
  return _query(_conn, from, select, where, orderBy, limit);
549
595
  },
550
596
 
551
- delete: (ids: string[], options?: SfDmlOptions) => _conn.delete(from, ids, options),
597
+ delete: async (ids: string[], options: SfDmlOptions | undefined = o?.dml) => processSaveResult(await _conn.delete(from, ids, options), o?.breakOnError),
552
598
 
553
- update: (records: SfUpdate<OI[N]>[], options?: SfDmlOptions) => _conn.update(from, records, options),
599
+ update: async (records: SfUpdate<OI[N]>[], options: SfDmlOptions | undefined = o?.dml) => processSaveResult(await _conn.update(from, records, options), o?.breakOnError),
554
600
 
555
- create: (records: SfCreate<OI[N]>[], options?: SfDmlOptions) => _conn.create(from, records, options),
601
+ create: async (records: SfCreate<OI[N]>[], options: SfDmlOptions | undefined = o?.dml) => processSaveResult(await _conn.create(from, records, options), o?.breakOnError),
556
602
 
557
- upsert: <K extends MandatoryCreateProps<OI[N]>>(records: SfUpsert<OI[N], K>[], key: K, options?: SfDmlOptions) => _conn.upsert(from, records, key, options),
603
+ upsert: async <K extends MandatoryCreateProps<OI[N]>>(records: SfUpsert<OI[N], K>[], key: K, options: SfDmlOptions | undefined = o?.dml) => processSaveResult(await _conn.upsert(from, records, key, options), o?.breakOnError),
558
604
 
559
605
  select: <S extends SfRootSelect<OI, N>>(select: S[]) => ({
560
606
 
@@ -570,17 +616,27 @@ export function getSfObject<OI>(_cfg: SfObjCfgIndex<OI>) {
570
616
 
571
617
  }),
572
618
 
573
- find: async (id: string, options?: SfQueryOptions) => {
619
+ find: async (id: string, options: SfQueryOptions | undefined = o?.query) => {
574
620
 
575
- const result = await _query(_conn, from, select, `Id = '${id}'`).limit(1).get(options);
621
+ const result = await _queryOne(_conn, from, select, id, options);
576
622
 
577
623
  if (result.records.length) {
578
624
  return result.records[0];
579
625
  }
580
626
  },
581
627
 
582
- selection: select
628
+ retrieve: async (id: string, options: SfQueryOptions | undefined = o?.query) => {
629
+
630
+ const result = await _queryOne(_conn, from, select, id, options);
631
+
632
+ if (!result.records.length) {
633
+ throw new SfBasicClientReadError(`Record with id '${id}' is not found in '${from}'.`);
634
+ }
635
+
636
+ return result.records[0];
637
+ },
583
638
 
639
+ selection: select
584
640
  })
585
641
  })
586
642
  };
@@ -588,8 +644,8 @@ export function getSfObject<OI>(_cfg: SfObjCfgIndex<OI>) {
588
644
  }
589
645
 
590
646
 
591
- export const getSfObjects = <OI>(cfg: SfObjCfgIndex<OI>) => (conn: ISfConnection) => {
592
- const _func = getSfObject<OI>(cfg);
647
+ export const getSfObjects = <OI>(cfg: SfObjCfgIndex<OI>) => (conn: ISfConnection, options?: SfClientOptions) => {
648
+ const _func = getSfObject<OI>(cfg, options);
593
649
  return (Object.keys(cfg) as KeyOf<OI>[]).reduce((p, n) => ({ ...p, [n]: _func(n, conn) }), {} as { [N in KeyOf<OI>]: SfObjActions<OI, N> });
594
650
  }
595
651