sfobjects-basic-client 1.1.9 → 1.2.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.d.ts +17 -6
- package/dist/index.js +21 -7
- package/package.json +21 -21
- package/src/index.ts +47 -13
package/dist/index.d.ts
CHANGED
|
@@ -34,10 +34,10 @@ export type SfProjection<OO, O extends OO, S> = {
|
|
|
34
34
|
} ? (NonNullable<O[K]> extends OO ? SfProjection<OO, NonNullable<O[K]>, S['select'][0]> : (NonNullable<O[K]> extends ChildTable<OO> ? Readonly<ChildTable<SfProjection<OO, NonNullable<O[K]>['records'][0], S['select'][0]>>> : never)) : never));
|
|
35
35
|
};
|
|
36
36
|
declare const SINGULAR_OP_KEYS: readonly ["eq", "equals", "=", "==", "ne", "!=", "<>", "lt", "<", "less than", "gt", ">", "greater than", "lte", "<=", "less than or equal", "gte", ">=", "greater than or equal", "like", "nlike", "not like"];
|
|
37
|
-
declare const
|
|
37
|
+
declare const PLURAL_OR_SJ_OP_KEYS: readonly ["in", "nin", "not in"];
|
|
38
38
|
declare const LOGICAL_OP_KEYS: readonly ["__and", "__or", "__not"];
|
|
39
39
|
type SfSingularOpKeys = typeof SINGULAR_OP_KEYS[number];
|
|
40
|
-
type SfPluralOpKeys = typeof
|
|
40
|
+
type SfPluralOpKeys = typeof PLURAL_OR_SJ_OP_KEYS[number];
|
|
41
41
|
type SfLogicalOpKeys = typeof LOGICAL_OP_KEYS[number];
|
|
42
42
|
type SfValueOpKeys = SfSingularOpKeys | SfPluralOpKeys;
|
|
43
43
|
interface SfWhereOp<OP extends SfValueOpKeys, V> {
|
|
@@ -47,15 +47,26 @@ interface SfWhereOp<OP extends SfValueOpKeys, V> {
|
|
|
47
47
|
type ParentOrPrimitiveProps<OO, O extends OO> = {
|
|
48
48
|
[K in KeyOf<O>]: NonNullable<O[K]> extends SfPrimitiveType ? K : NonNullable<O[K]> extends OO ? K : never;
|
|
49
49
|
}[KeyOf<O>];
|
|
50
|
-
type SfWhere<OO, O extends OO> = {
|
|
50
|
+
type SfWhere<OO, O extends OO, OI = never> = {
|
|
51
51
|
[K in ParentOrPrimitiveProps<OO, O>]+?: (NonNullable<O[K]> extends SfPrimitiveType ? (O[K] | O[K][] | {
|
|
52
52
|
[OPK in SfSingularOpKeys]: SfWhereOp<OPK, O[K]>;
|
|
53
53
|
}[SfSingularOpKeys] | {
|
|
54
|
-
[OPK in SfPluralOpKeys]: SfWhereOp<OPK, O[K][]>;
|
|
54
|
+
[OPK in SfPluralOpKeys]: SfWhereOp<OPK, O[K][] | (OI extends never ? never : SfWhereSemiJoinOps<OI>)>;
|
|
55
55
|
}[SfPluralOpKeys]) : (NonNullable<O[K]> extends OO ? SfWhere<OO, NonNullable<O[K]>> : never));
|
|
56
56
|
} | {
|
|
57
57
|
[K in SfLogicalOpKeys]+?: SfWhere<OO, O>;
|
|
58
58
|
} | SfWhere<OO, O>[];
|
|
59
|
+
type SfWhereSemiJoinOpSelect<O> = {
|
|
60
|
+
[K in KeyOf<O>]: NonNullable<O[K]> extends string ? K : never;
|
|
61
|
+
}[KeyOf<O>];
|
|
62
|
+
interface SfWhereSemiJoinOp<OI, N extends KeyOf<OI>> {
|
|
63
|
+
from: N;
|
|
64
|
+
select: SfWhereSemiJoinOpSelect<OI[N]>;
|
|
65
|
+
where?: SfWhere<GetObjectTypes<OI>, OI[N]>;
|
|
66
|
+
}
|
|
67
|
+
type SfWhereSemiJoinOps<OI> = {
|
|
68
|
+
[N in KeyOf<OI>]: SfWhereSemiJoinOp<OI, N>;
|
|
69
|
+
}[KeyOf<OI>];
|
|
59
70
|
type SfOrderType = 'asc' | 'desc';
|
|
60
71
|
type SfOrderBy<OO, O extends OO> = {
|
|
61
72
|
[K in ParentOrPrimitiveProps<OO, O>]+?: NonNullable<O[K]> extends SfPrimitiveType ? SfOrderType : (NonNullable<O[K]> extends OO ? SfOrderBy<OO, NonNullable<O[K]>> : never);
|
|
@@ -82,7 +93,7 @@ type UpdateableProps<O> = {
|
|
|
82
93
|
}, K>) : never;
|
|
83
94
|
}[KeyOf<O>];
|
|
84
95
|
export type SfRootSelect<OI, N extends KeyOf<OI>> = SfSelect<GetObjectTypes<OI>, OI[N]>;
|
|
85
|
-
export type SfRootWhere<OI, N extends KeyOf<OI>> = SfWhere<GetObjectTypes<OI>, OI[N]>;
|
|
96
|
+
export type SfRootWhere<OI, N extends KeyOf<OI>> = SfWhere<GetObjectTypes<OI>, OI[N], OI>;
|
|
86
97
|
export type SfRootOrderBy<OI, N extends KeyOf<OI>> = SfOrderBy<GetObjectTypes<OI>, OI[N]>;
|
|
87
98
|
export type SfRootSelectProjection<OI, N extends KeyOf<OI>, S extends SfRootSelect<OI, N>> = SfProjection<GetObjectTypes<OI>, OI[N], S>;
|
|
88
99
|
export type SfCreate<O> = {
|
|
@@ -172,7 +183,7 @@ export interface SfOrderByAction<OI, N extends KeyOf<OI>, S extends SfRootSelect
|
|
|
172
183
|
orderBy: <R extends SfRootOrderBy<OI, N>>(orderBy: R) => (SfQueryActions<OI, N, S> & SfLimitAction<OI, N, S>);
|
|
173
184
|
}
|
|
174
185
|
export interface SfWhereActions<OI, N extends KeyOf<OI>, S extends SfRootSelect<OI, N>> {
|
|
175
|
-
where: <W extends SfRootWhere<OI, N>>(where: W) => (SfQueryActions<OI, N, S> & SfOrderByAction<OI, N, S>);
|
|
186
|
+
where: <W extends SfRootWhere<OI, N>>(where: W) => (SfQueryActions<OI, N, S> & SfOrderByAction<OI, N, S> & SfLimitAction<OI, N, S>);
|
|
176
187
|
}
|
|
177
188
|
export interface SfQueryAditionalActions<OI, N extends KeyOf<OI>, S extends SfRootSelect<OI, N>> {
|
|
178
189
|
find: (id: string, options?: SfQueryOptions) => Promise<SfRootSelectProjection<OI, N, S> | undefined>;
|
package/dist/index.js
CHANGED
|
@@ -49,7 +49,7 @@ const SINGULAR_OP_KEYS = [
|
|
|
49
49
|
...OP_KEYS_LIKE,
|
|
50
50
|
...OP_KEYS_NLIKE
|
|
51
51
|
];
|
|
52
|
-
const
|
|
52
|
+
const PLURAL_OR_SJ_OP_KEYS = [
|
|
53
53
|
...OP_KEYS_IN,
|
|
54
54
|
...OP_KEYS_NIN
|
|
55
55
|
];
|
|
@@ -65,10 +65,10 @@ const OP_RULES = [
|
|
|
65
65
|
{ ops: OP_KEYS_LTE, soqlOp: '<=' },
|
|
66
66
|
{ ops: OP_KEYS_GT, soqlOp: '>' },
|
|
67
67
|
{ ops: OP_KEYS_GTE, soqlOp: '>=' },
|
|
68
|
-
{ ops: OP_KEYS_IN, soqlOp: 'in', isPlural: true },
|
|
69
|
-
{ ops: OP_KEYS_NIN, soqlOp: 'in', isNot: true, isPlural: true },
|
|
68
|
+
{ ops: OP_KEYS_IN, soqlOp: 'in', isPlural: true, isSemiJoin: true },
|
|
69
|
+
{ ops: OP_KEYS_NIN, soqlOp: 'in', isNot: true, isPlural: true, isSemiJoin: true },
|
|
70
70
|
{ ops: OP_KEYS_LIKE, soqlOp: 'like' },
|
|
71
|
-
{ ops: OP_KEYS_NLIKE, soqlOp: 'like', isNot: true }
|
|
71
|
+
{ ops: OP_KEYS_NLIKE, soqlOp: 'like', isNot: true }
|
|
72
72
|
];
|
|
73
73
|
class SfBasicClientSaveError extends Error {
|
|
74
74
|
constructor(errors) {
|
|
@@ -177,6 +177,12 @@ function constructSoql(_cfg) {
|
|
|
177
177
|
.filter(Boolean)
|
|
178
178
|
.join(', ');
|
|
179
179
|
}
|
|
180
|
+
function _constructSemiJoinStatement(sj) {
|
|
181
|
+
const { from, select, where } = sj;
|
|
182
|
+
if (typeof from === 'string' && typeof select === 'string' && from && select) {
|
|
183
|
+
return `(${_constructFullQuery(from, from, [select], where)})`;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
180
186
|
function _constructWhereStatement(objName, where, o) {
|
|
181
187
|
if (typeof where === 'string') {
|
|
182
188
|
return where;
|
|
@@ -199,13 +205,21 @@ function constructSoql(_cfg) {
|
|
|
199
205
|
if (op !== undefined && value !== undefined) {
|
|
200
206
|
const opRule = OP_RULES.find(r => r.ops.some(rop => (rop === op)));
|
|
201
207
|
if (opRule) {
|
|
202
|
-
const { soqlOp, isNot, isPlural } = opRule;
|
|
203
|
-
if (
|
|
208
|
+
const { soqlOp, isNot, isPlural, isSemiJoin } = opRule;
|
|
209
|
+
if (isSemiJoin && isPlainObject(value)) {
|
|
210
|
+
return [
|
|
211
|
+
keyWithPrefix,
|
|
212
|
+
`${isNot ? 'not ' : ''}${soqlOp}`,
|
|
213
|
+
_constructSemiJoinStatement(value)
|
|
214
|
+
]
|
|
215
|
+
.join(' ');
|
|
216
|
+
}
|
|
217
|
+
else if ((isPlural !== null && isPlural !== void 0 ? isPlural : false) === Array.isArray(value)) {
|
|
204
218
|
return [
|
|
205
219
|
isNot ? 'not (' : '',
|
|
206
220
|
keyWithPrefix,
|
|
207
221
|
soqlOp,
|
|
208
|
-
Array.isArray(value) ? `( ${value.map(v => _escapeVal(objName, propName, v)).join(',')} )` : _escapeVal(objName, propName, value),
|
|
222
|
+
Array.isArray(value) ? `( ${value.map(v => _escapeVal(objName, propName, v)).join(', ')} )` : _escapeVal(objName, propName, value),
|
|
209
223
|
isNot ? ')' : '',
|
|
210
224
|
]
|
|
211
225
|
.filter(Boolean)
|
package/package.json
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "sfobjects-basic-client",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Basic Salesforce Client to use together with sfobjects-to-typescript lib",
|
|
5
|
-
"license": "ISC",
|
|
6
|
-
"author": "Murad Aliyev",
|
|
7
|
-
"main": "dist/index.js",
|
|
8
|
-
"repository": {
|
|
9
|
-
"type": "git",
|
|
10
|
-
"url": "https://github.com/muradaliyev/sfobjects-basic-client"
|
|
11
|
-
},
|
|
12
|
-
"scripts": {
|
|
13
|
-
"build": "npm run clean && tsc",
|
|
14
|
-
"clean": "rimraf dist"
|
|
15
|
-
},
|
|
16
|
-
"devDependencies": {
|
|
17
|
-
"@types/node": "^25.9.4",
|
|
18
|
-
"rimraf": "^6.1.2",
|
|
19
|
-
"typescript": "^5.9.3"
|
|
20
|
-
}
|
|
21
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "sfobjects-basic-client",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Basic Salesforce Client to use together with sfobjects-to-typescript lib",
|
|
5
|
+
"license": "ISC",
|
|
6
|
+
"author": "Murad Aliyev",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/muradaliyev/sfobjects-basic-client"
|
|
11
|
+
},
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "npm run clean && tsc",
|
|
14
|
+
"clean": "rimraf dist"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@types/node": "^25.9.4",
|
|
18
|
+
"rimraf": "^6.1.2",
|
|
19
|
+
"typescript": "^5.9.3"
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -67,7 +67,7 @@ const SINGULAR_OP_KEYS = [
|
|
|
67
67
|
...OP_KEYS_NLIKE
|
|
68
68
|
] as const;
|
|
69
69
|
|
|
70
|
-
const
|
|
70
|
+
const PLURAL_OR_SJ_OP_KEYS = [
|
|
71
71
|
...OP_KEYS_IN,
|
|
72
72
|
...OP_KEYS_NIN
|
|
73
73
|
] as const;
|
|
@@ -78,15 +78,18 @@ const LOGICAL_OP_KEYS = [
|
|
|
78
78
|
OP_KEY_NOT
|
|
79
79
|
] as const;
|
|
80
80
|
|
|
81
|
+
|
|
81
82
|
type SfSingularOpKeys = typeof SINGULAR_OP_KEYS[number];
|
|
82
|
-
type SfPluralOpKeys = typeof
|
|
83
|
+
type SfPluralOpKeys = typeof PLURAL_OR_SJ_OP_KEYS[number];
|
|
83
84
|
type SfLogicalOpKeys = typeof LOGICAL_OP_KEYS[number];
|
|
85
|
+
|
|
84
86
|
type SfValueOpKeys = SfSingularOpKeys | SfPluralOpKeys;
|
|
85
87
|
|
|
86
88
|
interface SfOpRule {
|
|
87
89
|
ops: readonly SfValueOpKeys[];
|
|
88
90
|
isNot?: boolean;
|
|
89
91
|
isPlural?: boolean;
|
|
92
|
+
isSemiJoin?: boolean;
|
|
90
93
|
soqlOp: string;
|
|
91
94
|
}
|
|
92
95
|
|
|
@@ -97,20 +100,23 @@ const OP_RULES: SfOpRule[] = [
|
|
|
97
100
|
{ ops: OP_KEYS_LTE, soqlOp: '<=' },
|
|
98
101
|
{ ops: OP_KEYS_GT, soqlOp: '>' },
|
|
99
102
|
{ ops: OP_KEYS_GTE, soqlOp: '>=' },
|
|
100
|
-
{ ops: OP_KEYS_IN, soqlOp: 'in', isPlural: true },
|
|
101
|
-
{ ops: OP_KEYS_NIN, soqlOp: 'in', isNot: true, isPlural: true },
|
|
103
|
+
{ ops: OP_KEYS_IN, soqlOp: 'in', isPlural: true, isSemiJoin: true },
|
|
104
|
+
{ ops: OP_KEYS_NIN, soqlOp: 'in', isNot: true, isPlural: true, isSemiJoin: true },
|
|
102
105
|
{ ops: OP_KEYS_LIKE, soqlOp: 'like' },
|
|
103
|
-
{ ops: OP_KEYS_NLIKE, soqlOp: 'like', isNot: true }
|
|
106
|
+
{ ops: OP_KEYS_NLIKE, soqlOp: 'like', isNot: true }
|
|
104
107
|
]
|
|
105
108
|
|
|
106
109
|
interface SfWhereOp<OP extends SfValueOpKeys, V> { op: OP; value: V; }
|
|
107
110
|
|
|
108
111
|
type ParentOrPrimitiveProps<OO, O extends OO> = { [K in KeyOf<O>]: NonNullable<O[K]> extends SfPrimitiveType ? K : NonNullable<O[K]> extends OO ? K : never }[KeyOf<O>];
|
|
109
112
|
|
|
110
|
-
type SfWhere<OO, O extends OO> = {
|
|
113
|
+
type SfWhere<OO, O extends OO, OI = never> = {
|
|
111
114
|
[K in ParentOrPrimitiveProps<OO, O>]+?: (
|
|
112
115
|
NonNullable<O[K]> extends SfPrimitiveType ? (
|
|
113
|
-
O[K] |
|
|
116
|
+
O[K] |
|
|
117
|
+
O[K][] |
|
|
118
|
+
{ [OPK in SfSingularOpKeys]: SfWhereOp<OPK, O[K]> }[SfSingularOpKeys] |
|
|
119
|
+
{ [OPK in SfPluralOpKeys]: SfWhereOp<OPK, O[K][] | (OI extends never ? never : SfWhereSemiJoinOps<OI>)> }[SfPluralOpKeys]
|
|
114
120
|
) : (
|
|
115
121
|
NonNullable<O[K]> extends OO ? SfWhere<OO, NonNullable<O[K]>> : never
|
|
116
122
|
)
|
|
@@ -118,6 +124,15 @@ type SfWhere<OO, O extends OO> = {
|
|
|
118
124
|
} | { [K in SfLogicalOpKeys]+?: SfWhere<OO, O> } | SfWhere<OO, O>[];
|
|
119
125
|
|
|
120
126
|
|
|
127
|
+
type SfWhereSemiJoinOpSelect<O> = { [K in KeyOf<O>]: NonNullable<O[K]> extends string ? K : never }[KeyOf<O>]
|
|
128
|
+
|
|
129
|
+
interface SfWhereSemiJoinOp<OI, N extends KeyOf<OI>> {
|
|
130
|
+
from: N;
|
|
131
|
+
select: SfWhereSemiJoinOpSelect<OI[N]>;
|
|
132
|
+
where?: SfWhere<GetObjectTypes<OI>, OI[N]>;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
type SfWhereSemiJoinOps<OI> = { [N in KeyOf<OI>]: SfWhereSemiJoinOp<OI, N> }[KeyOf<OI>];
|
|
121
136
|
|
|
122
137
|
// order by
|
|
123
138
|
|
|
@@ -164,7 +179,7 @@ type UpdateableProps<O> = {
|
|
|
164
179
|
|
|
165
180
|
export type SfRootSelect<OI, N extends KeyOf<OI>> = SfSelect<GetObjectTypes<OI>, OI[N]>;
|
|
166
181
|
|
|
167
|
-
export type SfRootWhere<OI, N extends KeyOf<OI>> = SfWhere<GetObjectTypes<OI>, OI[N]>;
|
|
182
|
+
export type SfRootWhere<OI, N extends KeyOf<OI>> = SfWhere<GetObjectTypes<OI>, OI[N], OI>;// | SfWhereSemiJoin<OI, OI[N]>;
|
|
168
183
|
|
|
169
184
|
export type SfRootOrderBy<OI, N extends KeyOf<OI>> = SfOrderBy<GetObjectTypes<OI>, OI[N]>;
|
|
170
185
|
|
|
@@ -274,7 +289,7 @@ export interface SfOrderByAction<OI, N extends KeyOf<OI>, S extends SfRootSelect
|
|
|
274
289
|
}
|
|
275
290
|
|
|
276
291
|
export interface SfWhereActions<OI, N extends KeyOf<OI>, S extends SfRootSelect<OI, N>> {
|
|
277
|
-
where: <W extends SfRootWhere<OI, N>>(where: W) => (SfQueryActions<OI, N, S> & SfOrderByAction<OI, N, S>);
|
|
292
|
+
where: <W extends SfRootWhere<OI, N>>(where: W) => (SfQueryActions<OI, N, S> & SfOrderByAction<OI, N, S> & SfLimitAction<OI, N, S>);
|
|
278
293
|
}
|
|
279
294
|
|
|
280
295
|
export interface SfQueryAditionalActions<OI, N extends KeyOf<OI>, S extends SfRootSelect<OI, N>> {
|
|
@@ -357,9 +372,9 @@ export function constructSoql<OI>(_cfg: SfObjCfgIndex<OI>) {
|
|
|
357
372
|
}
|
|
358
373
|
|
|
359
374
|
throw `Unupported value type for where statement`;
|
|
360
|
-
|
|
361
375
|
}
|
|
362
376
|
|
|
377
|
+
|
|
363
378
|
function _constructFullQuery(
|
|
364
379
|
objName: string,
|
|
365
380
|
from: string,
|
|
@@ -448,6 +463,16 @@ export function constructSoql<OI>(_cfg: SfObjCfgIndex<OI>) {
|
|
|
448
463
|
.join(', ');
|
|
449
464
|
}
|
|
450
465
|
|
|
466
|
+
function _constructSemiJoinStatement(sj: Record<string, any>) {
|
|
467
|
+
|
|
468
|
+
const { from, select, where } = sj;
|
|
469
|
+
|
|
470
|
+
if (typeof from === 'string' && typeof select === 'string' && from && select) {
|
|
471
|
+
return `(${_constructFullQuery(from, from, [select], where)})`;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
|
|
451
476
|
function _constructWhereStatement(
|
|
452
477
|
objName: string,
|
|
453
478
|
where: string | Record<string, any>,
|
|
@@ -490,15 +515,24 @@ export function constructSoql<OI>(_cfg: SfObjCfgIndex<OI>) {
|
|
|
490
515
|
|
|
491
516
|
if (opRule) {
|
|
492
517
|
|
|
493
|
-
const { soqlOp, isNot, isPlural } = opRule;
|
|
518
|
+
const { soqlOp, isNot, isPlural, isSemiJoin } = opRule;
|
|
519
|
+
|
|
520
|
+
if (isSemiJoin && isPlainObject(value)) {
|
|
521
|
+
return [
|
|
522
|
+
keyWithPrefix,
|
|
523
|
+
`${isNot ? 'not ' : ''}${soqlOp}`,
|
|
524
|
+
_constructSemiJoinStatement(value)
|
|
525
|
+
]
|
|
526
|
+
.join(' ');
|
|
527
|
+
}
|
|
494
528
|
|
|
495
|
-
if ((isPlural ?? false) === Array.isArray(value)) {
|
|
529
|
+
else if ((isPlural ?? false) === Array.isArray(value)) {
|
|
496
530
|
|
|
497
531
|
return [
|
|
498
532
|
isNot ? 'not (' : '',
|
|
499
533
|
keyWithPrefix,
|
|
500
534
|
soqlOp,
|
|
501
|
-
Array.isArray(value) ? `( ${value.map(v => _escapeVal(objName, propName, v)).join(',')} )` : _escapeVal(objName, propName, value),
|
|
535
|
+
Array.isArray(value) ? `( ${value.map(v => _escapeVal(objName, propName, v)).join(', ')} )` : _escapeVal(objName, propName, value),
|
|
502
536
|
isNot ? ')' : '',
|
|
503
537
|
]
|
|
504
538
|
.filter(Boolean)
|