query-core 0.1.7 → 0.1.11

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/src/build.ts CHANGED
@@ -1,21 +1,21 @@
1
1
  import {Attribute, Attributes, Statement, StringMap} from './metadata';
2
2
 
3
- export function params(length: number, param: (i: number) => string, from?: number): string[] {
3
+ export function params(length: number, p: (i: number) => string, from?: number): string[] {
4
4
  if (from === undefined || from == null) {
5
5
  from = 0;
6
6
  }
7
7
  const ps: string[] = [];
8
8
  for (let i = 1; i <= length; i++) {
9
- ps.push(param(i + from));
9
+ ps.push(p(i + from));
10
10
  }
11
11
  return ps;
12
12
  }
13
- export function select<T>(obj: T, table: string, ks: Attribute[], buildParam: (i: number) => string, i?: number): Statement {
13
+ export function select<T>(obj: T, table: string, ks: Attribute[], buildParam: (i: number) => string, i?: number): Statement|undefined {
14
14
  if (!i) {
15
15
  i = 1;
16
16
  }
17
17
  if (ks.length === 1) {
18
- const field = (ks[0].field ? ks[0].field : ks[0].name);
18
+ const field = (ks[0].column ? ks[0].column : ks[0].name);
19
19
  if (typeof obj === 'number') {
20
20
  const query = `select * from ${table} where ${field} = ${obj}`;
21
21
  return { query, params: [] };
@@ -27,17 +27,19 @@ export function select<T>(obj: T, table: string, ks: Attribute[], buildParam: (i
27
27
  const cols: string[] = [];
28
28
  const args: any[] = [];
29
29
  for (const k of ks) {
30
- const field = (k.field ? k.field : k.name);
31
- cols.push(`${field} = ${buildParam(i++)}`);
32
- args.push(obj[k.name]);
30
+ if (k.name) {
31
+ const field = (k.column ? k.column : k.name);
32
+ cols.push(`${field} = ${buildParam(i++)}`);
33
+ args.push((obj as any)[k.name]);
34
+ }
33
35
  }
34
36
  const query = `select * from ${table} where ${cols.join(' and ')}`;
35
37
  return { query, params: args };
36
38
  } else {
37
- return null;
39
+ return undefined;
38
40
  }
39
41
  }
40
- export function exist<T>(obj: T, table: string, ks: Attribute[], buildParam: (i: number) => string, col?: string, i?: number): Statement {
42
+ export function exist<T>(obj: T, table: string, ks: Attribute[], buildParam: (i: number) => string, col?: string, i?: number): Statement|undefined {
41
43
  if (!i) {
42
44
  i = 1;
43
45
  }
@@ -45,7 +47,7 @@ export function exist<T>(obj: T, table: string, ks: Attribute[], buildParam: (i:
45
47
  col = '*';
46
48
  }
47
49
  if (ks.length === 1) {
48
- const field = (ks[0].field ? ks[0].field : ks[0].name);
50
+ const field = (ks[0].column ? ks[0].column : ks[0].name);
49
51
  if (typeof obj === 'number') {
50
52
  const query = `select ${col} from ${table} where ${field} = ${obj}`;
51
53
  return { query, params: [] };
@@ -57,22 +59,24 @@ export function exist<T>(obj: T, table: string, ks: Attribute[], buildParam: (i:
57
59
  const cols: string[] = [];
58
60
  const args: any[] = [];
59
61
  for (const k of ks) {
60
- const field = (k.field ? k.field : k.name);
61
- cols.push(`${field} = ${buildParam(i++)}`);
62
- args.push(obj[k.name]);
62
+ if (k.name) {
63
+ const field = (k.column ? k.column : k.name);
64
+ cols.push(`${field} = ${buildParam(i++)}`);
65
+ args.push((obj as any)[k.name]);
66
+ }
63
67
  }
64
68
  const query = `select * from ${table} where ${cols.join(' and ')}`;
65
69
  return { query, params: args };
66
70
  } else {
67
- return null;
71
+ return undefined;
68
72
  }
69
73
  }
70
- export function buildToDelete<T>(obj: T, table: string, ks: Attribute[], buildParam: (i: number) => string, i?: number): Statement {
74
+ export function buildToDelete<T>(obj: T, table: string, ks: Attribute[], buildParam: (i: number) => string, i?: number): Statement|undefined {
71
75
  if (!i) {
72
76
  i = 1;
73
77
  }
74
78
  if (ks.length === 1) {
75
- const field = (ks[0].field ? ks[0].field : ks[0].name);
79
+ const field = (ks[0].column ? ks[0].column : ks[0].name);
76
80
  if (typeof obj === 'number') {
77
81
  const query = `delete from ${table} where ${field} = ${obj}`;
78
82
  return { query, params: [] };
@@ -84,14 +88,16 @@ export function buildToDelete<T>(obj: T, table: string, ks: Attribute[], buildPa
84
88
  const cols: string[] = [];
85
89
  const args: any[] = [];
86
90
  for (const k of ks) {
87
- const field = (k.field ? k.field : k.name);
88
- cols.push(`${field} = ${buildParam(i++)}`);
89
- args.push(obj[k.name]);
91
+ if (k.name) {
92
+ const field = (k.column ? k.column : k.name);
93
+ cols.push(`${field} = ${buildParam(i++)}`);
94
+ args.push((obj as any)[k.name]);
95
+ }
90
96
  }
91
97
  const query = `delete from ${table} where ${cols.join(' and ')}`;
92
98
  return { query, params: args };
93
99
  } else {
94
- return null;
100
+ return undefined;
95
101
  }
96
102
  }
97
103
  export function insert<T>(exec: (sql: string, args?: any[]) => Promise<number>, obj: T, table: string, attrs: Attributes, buildParam: (i: number) => string, ver?: string, i?: number): Promise<number> {
@@ -102,24 +108,25 @@ export function insert<T>(exec: (sql: string, args?: any[]) => Promise<number>,
102
108
  return exec(stm.query, stm.params);
103
109
  }
104
110
  }
105
- export function buildToInsert<T>(obj: T, table: string, attrs: Attributes, buildParam: (i: number) => string, ver?: string, i?: number): Statement {
111
+ export function buildToInsert<T>(obj: T, table: string, attrs: Attributes, buildParam: (i: number) => string, ver?: string, i?: number): Statement|undefined {
106
112
  if (!i) {
107
113
  i = 1;
108
114
  }
115
+ const o: any = obj;
109
116
  const ks = Object.keys(attrs);
110
117
  const cols: string[] = [];
111
118
  const values: string[] = [];
112
119
  const args: any[] = [];
113
120
  let isVersion = false;
114
121
  for (const k of ks) {
115
- let v = obj[k];
122
+ let v = o[k];
116
123
  const attr = attrs[k];
117
124
  if (attr && !attr.ignored && !attr.noinsert) {
118
125
  if (v === undefined || v == null) {
119
126
  v = attr.default;
120
127
  }
121
128
  if (v !== undefined && v != null) {
122
- const field = (attr.field ? attr.field : k);
129
+ const field = (attr.column ? attr.column : k);
123
130
  cols.push(field);
124
131
  if (k === ver) {
125
132
  isVersion = true;
@@ -158,87 +165,167 @@ export function buildToInsert<T>(obj: T, table: string, attrs: Attributes, build
158
165
  }
159
166
  if (!isVersion && ver && ver.length > 0) {
160
167
  const attr = attrs[ver];
161
- const field = (attr.field ? attr.field : ver);
168
+ const field = (attr.column ? attr.column : ver);
162
169
  cols.push(field);
163
170
  values.push(`${1}`);
164
171
  }
165
172
  if (cols.length === 0) {
166
- return null;
173
+ return undefined;
167
174
  } else {
168
175
  const query = `insert into ${table}(${cols.join(',')})values(${values.join(',')})`;
169
176
  return { query, params: args };
170
177
  }
171
178
  }
172
- export function insertBatch<T>(exec: (sql: string, args?: any[]) => Promise<number>, objs: T[], table: string, attrs: Attributes, buildParam: (i: number) => string, i?: number): Promise<number> {
173
- const stm = buildToInsertBatch(objs, table, attrs, buildParam, i);
179
+ export function insertBatch<T>(exec: (sql: string, args?: any[]) => Promise<number>, objs: T[], table: string, attrs: Attributes, buildParam: ((i: number) => string)|boolean, ver?: string, i?: number): Promise<number> {
180
+ const stm = buildToInsertBatch(objs, table, attrs, buildParam, ver, i);
174
181
  if (!stm) {
175
182
  return Promise.resolve(0);
176
183
  } else {
177
184
  return exec(stm.query, stm.params);
178
185
  }
179
186
  }
180
- export function buildToInsertBatch<T>(objs: T[], table: string, attrs: Attributes, buildParam: (i: number) => string, i?: number): Statement {
187
+ function buildOracleParam(i: number): string {
188
+ return ':' + i;
189
+ }
190
+ export function buildToInsertBatch<T>(objs: T[], table: string, attrs: Attributes, buildParam: ((i: number) => string) | boolean, ver?: string, i?: number): Statement|undefined {
181
191
  if (!i) {
182
192
  i = 1;
183
193
  }
184
194
  const ks = Object.keys(attrs);
185
- const cols: string[] = [];
186
- const rows: string[] = [];
187
195
  const args: any[] = [];
188
- for (const k of ks) {
189
- const attr = attrs[k];
190
- if (attr && !attr.ignored && !attr.noinsert) {
191
- const field = (attr.field ? attr.field : k);
192
- cols.push(field);
193
- }
194
- }
195
- for (const obj of objs) {
196
- const values: string[] = [];
196
+ if (buildParam && typeof buildParam === 'function') {
197
+ const cols: string[] = [];
198
+ const rows: string[] = [];
197
199
  for (const k of ks) {
198
200
  const attr = attrs[k];
199
201
  if (attr && !attr.ignored && !attr.noinsert) {
200
- let v = obj[k];
201
- if (v === undefined || v === null) {
202
- v = attr.default;
203
- }
204
- // let x: string;
205
- if (attr.version) {
206
- values.push('1');
207
- } else if (v === undefined || v == null) {
208
- values.push('null');
209
- } else if (v === '') {
210
- values.push(`''`);
211
- } else if (typeof v === 'number') {
212
- values.push(toString(v));
213
- } else if (typeof v === 'boolean') {
214
- if (attr.true === undefined) {
215
- if (v === true) {
216
- values.push(`true`);
202
+ const field = (attr.column ? attr.column : k);
203
+ cols.push(field);
204
+ }
205
+ }
206
+ for (const obj of objs) {
207
+ const values: string[] = [];
208
+ for (const k of ks) {
209
+ const attr = attrs[k];
210
+ if (attr && !attr.ignored && !attr.noinsert) {
211
+ let v = (obj as any)[k];
212
+ if (v === undefined || v === null) {
213
+ v = attr.default;
214
+ }
215
+ // let x: string;
216
+ if (attr.version) {
217
+ values.push('1');
218
+ } else if (v === undefined || v == null) {
219
+ values.push('null');
220
+ } else if (v === '') {
221
+ values.push(`''`);
222
+ } else if (typeof v === 'number') {
223
+ values.push(toString(v));
224
+ } else if (typeof v === 'boolean') {
225
+ if (attr.true === undefined) {
226
+ if (v === true) {
227
+ values.push(`true`);
228
+ } else {
229
+ values.push(`false`);
230
+ }
217
231
  } else {
218
- values.push(`false`);
232
+ const p = buildParam(i++);
233
+ values.push(p);
234
+ if (v === true) {
235
+ const v2 = (attr.true ? attr.true : '1');
236
+ args.push(v2);
237
+ } else {
238
+ const v2 = (attr.false ? attr.false : '0');
239
+ args.push(v2);
240
+ }
219
241
  }
220
242
  } else {
221
243
  const p = buildParam(i++);
222
244
  values.push(p);
223
- if (v === true) {
224
- const v2 = (attr.true ? attr.true : '1');
225
- args.push(v2);
245
+ args.push(v);
246
+ }
247
+ }
248
+ }
249
+ rows.push(`(${values.join(',')})`);
250
+ }
251
+ const query = `insert into ${table}(${cols.join(',')})values ${rows.join(',')}`;
252
+ return { query, params: args };
253
+ } else {
254
+ let notSkipInvalid = false;
255
+ if (buildParam === true) {
256
+ notSkipInvalid = true;
257
+ }
258
+ const rows: string[] = [];
259
+ for (const obj of objs) {
260
+ const cols: string[] = [];
261
+ const values: string[] = [];
262
+ let isVersion = false;
263
+ for (const k of ks) {
264
+ let v = (obj as any)[k];
265
+ const attr = attrs[k];
266
+ if (attr && !attr.ignored && !attr.noinsert) {
267
+ if (v === undefined || v == null) {
268
+ v = attr.default;
269
+ }
270
+ if (v !== undefined && v != null) {
271
+ const field = (attr.column ? attr.column : k);
272
+ cols.push(field);
273
+ if (k === ver) {
274
+ isVersion = true;
275
+ values.push(`${1}`);
226
276
  } else {
227
- const v2 = (attr.false ? attr.false : '0');
228
- args.push(v2);
277
+ if (v === '') {
278
+ values.push(`''`);
279
+ } else if (typeof v === 'number') {
280
+ values.push(toString(v));
281
+ } else if (typeof v === 'boolean') {
282
+ if (attr.true === undefined) {
283
+ if (v === true) {
284
+ values.push(`true`);
285
+ } else {
286
+ values.push(`false`);
287
+ }
288
+ } else {
289
+ const p = buildOracleParam(i++);
290
+ values.push(p);
291
+ if (v === true) {
292
+ const v2 = (attr.true ? attr.true : '1');
293
+ args.push(v2);
294
+ } else {
295
+ const v2 = (attr.false ? attr.false : '0');
296
+ args.push(v2);
297
+ }
298
+ }
299
+ } else {
300
+ const p = buildOracleParam(i++);
301
+ values.push(p);
302
+ args.push(v);
303
+ }
229
304
  }
230
305
  }
231
- } else {
232
- const p = buildParam(i++);
233
- values.push(p);
234
- args.push(v);
235
306
  }
236
307
  }
308
+ if (!isVersion && ver && ver.length > 0) {
309
+ const attr = attrs[ver];
310
+ const field = (attr.column ? attr.column : ver);
311
+ cols.push(field);
312
+ values.push(`${1}`);
313
+ }
314
+ if (cols.length === 0) {
315
+ if (notSkipInvalid) {
316
+ return undefined;
317
+ }
318
+ } else {
319
+ const s = `into ${table}(${cols.join(',')})values(${values.join(',')})`;
320
+ rows.push(s);
321
+ }
322
+ }
323
+ if (rows.length === 0) {
324
+ return undefined;
237
325
  }
238
- rows.push(`(${values.join(',')})`);
326
+ const query = `insert all ${rows.join(' ')} select * from dual`;
327
+ return { query, params: args };
239
328
  }
240
- const query = `insert into ${table}(${cols.join(',')})values ${rows.join(',')}`;
241
- return { query, params: args };
242
329
  }
243
330
  export function update<T>(exec: (sql: string, args?: any[]) => Promise<number>, obj: T, table: string, attrs: Attributes, buildParam: (i: number) => string, ver?: string, i?: number): Promise<number> {
244
331
  const stm = buildToUpdate(obj, table, attrs, buildParam, ver, i);
@@ -248,17 +335,18 @@ export function update<T>(exec: (sql: string, args?: any[]) => Promise<number>,
248
335
  return exec(stm.query, stm.params);
249
336
  }
250
337
  }
251
- export function buildToUpdate<T>(obj: T, table: string, attrs: Attributes, buildParam: (i: number) => string, ver?: string, i?: number): Statement {
338
+ export function buildToUpdate<T>(obj: T, table: string, attrs: Attributes, buildParam: (i: number) => string, ver?: string, i?: number): Statement|undefined {
252
339
  if (!i) {
253
340
  i = 1;
254
341
  }
342
+ const o: any = obj;
255
343
  const ks = Object.keys(attrs);
256
344
  const pks: Attribute[] = [];
257
345
  const colSet: string[] = [];
258
346
  const colQuery: string[] = [];
259
347
  const args: any[] = [];
260
348
  for (const k of ks) {
261
- const v = obj[k];
349
+ const v = o[k];
262
350
  if (v !== undefined) {
263
351
  const attr = attrs[k];
264
352
  attr.name = k;
@@ -266,7 +354,7 @@ export function buildToUpdate<T>(obj: T, table: string, attrs: Attributes, build
266
354
  if (attr.key) {
267
355
  pks.push(attr);
268
356
  } else if (!attr.noupdate) {
269
- const field = (attr.field ? attr.field : k);
357
+ const field = (attr.column ? attr.column : k);
270
358
  let x: string;
271
359
  if (v == null) {
272
360
  x = 'null';
@@ -301,12 +389,13 @@ export function buildToUpdate<T>(obj: T, table: string, attrs: Attributes, build
301
389
  }
302
390
  }
303
391
  for (const pk of pks) {
304
- const v = obj[pk.name];
392
+ const na = (pk.name ? pk.name : '');
393
+ const v = o[na];
305
394
  if (!v) {
306
- return null;
395
+ return undefined;
307
396
  } else {
308
- const attr = attrs[pk.name];
309
- const field = (attr.field ? attr.field : pk.name);
397
+ const attr = attrs[na];
398
+ const field = (attr.column ? attr.column : pk.name);
310
399
  let x: string;
311
400
  if (v == null) {
312
401
  x = 'null';
@@ -332,18 +421,18 @@ export function buildToUpdate<T>(obj: T, table: string, attrs: Attributes, build
332
421
  }
333
422
  }
334
423
  if (ver && ver.length > 0) {
335
- const v = obj[ver];
424
+ const v = o[ver];
336
425
  if (typeof v === 'number' && !isNaN(v)) {
337
426
  const attr = attrs[ver];
338
427
  if (attr) {
339
- const field = (attr.field ? attr.field : ver);
428
+ const field = (attr.column ? attr.column : ver);
340
429
  colSet.push(`${field}=${(1 + v)}`);
341
430
  colQuery.push(`${field}=${v}`);
342
431
  }
343
432
  }
344
433
  }
345
434
  if (colSet.length === 0 || colQuery.length === 0) {
346
- return null;
435
+ return undefined;
347
436
  } else {
348
437
  const query = `update ${table} set ${colSet.join(',')} where ${colQuery.join(' and ')}`;
349
438
  return { query, params: args };
@@ -357,24 +446,26 @@ export function updateBatch<T>(exec: (statements: Statement[]) => Promise<number
357
446
  return exec(stmts);
358
447
  }
359
448
  }
360
- export function buildToUpdateBatch<T>(objs: T[], table: string, attrs: Attributes, buildParam: (i: number) => string, notSkipInvalid?: boolean): Statement[] {
449
+ export function buildToUpdateBatch<T>(objs: T[], table: string, attrs: Attributes, buildParam: (i: number) => string, notSkipInvalid?: boolean): Statement[]|undefined {
361
450
  const sts: Statement[] = [];
362
451
  const meta = metadata(attrs);
363
452
  if (!meta.keys || meta.keys.length === 0) {
364
- return null;
453
+ return undefined;
365
454
  }
366
455
  for (const obj of objs) {
456
+ const o: any = obj;
367
457
  let i = 1;
368
- const ks = Object.keys(obj);
458
+ const ks = Object.keys(o);
369
459
  const colSet: string[] = [];
370
460
  const colQuery: string[] = [];
371
461
  const args: any[] = [];
372
462
  for (const k of ks) {
373
- const v = obj[k];
463
+ const v = o[k];
374
464
  if (v !== undefined) {
375
465
  const attr = attrs[k];
466
+ attr.name = k;
376
467
  if (attr && !attr.ignored && !attr.key && !attr.version && !attr.noupdate) {
377
- const field = (attr.field ? attr.field : k);
468
+ const field = (attr.column ? attr.column : k);
378
469
  let x: string;
379
470
  if (v == null) {
380
471
  x = 'null';
@@ -409,12 +500,13 @@ export function buildToUpdateBatch<T>(objs: T[], table: string, attrs: Attribute
409
500
  }
410
501
  let valid = true;
411
502
  for (const pk of meta.keys) {
412
- const v = obj[pk.name];
503
+ const na = (pk.name ? pk.name : '');
504
+ const v = o[na];
413
505
  if (!v) {
414
506
  valid = false;
415
507
  } else {
416
- const attr = attrs[pk.name];
417
- const field = (attr.field ? attr.field : pk.name);
508
+ const attr = attrs[na];
509
+ const field = (attr.column ? attr.column : pk.name);
418
510
  let x: string;
419
511
  if (v == null) {
420
512
  x = 'null';
@@ -441,16 +533,16 @@ export function buildToUpdateBatch<T>(objs: T[], table: string, attrs: Attribute
441
533
  }
442
534
  if (!valid || colSet.length === 0 || colQuery.length === 0) {
443
535
  if (notSkipInvalid) {
444
- return null;
536
+ return undefined;
445
537
  }
446
538
  } else {
447
539
  const ver = meta.version;
448
540
  if (ver && ver.length > 0) {
449
- const v = obj[ver];
541
+ const v = o[ver];
450
542
  if (typeof v === 'number' && !isNaN(v)) {
451
543
  const attr = attrs[ver];
452
544
  if (attr) {
453
- const field = (attr.field ? attr.field : ver);
545
+ const field = (attr.column ? attr.column : ver);
454
546
  colSet.push(`${field}=${(1 + v)}`);
455
547
  colQuery.push(`${field}=${v}`);
456
548
  }
@@ -463,7 +555,7 @@ export function buildToUpdateBatch<T>(objs: T[], table: string, attrs: Attribute
463
555
  }
464
556
  return sts;
465
557
  }
466
- export function version(attrs: Attributes): Attribute {
558
+ export function version(attrs: Attributes): Attribute|undefined {
467
559
  const ks = Object.keys(attrs);
468
560
  for (const k of ks) {
469
561
  const attr = attrs[k];
@@ -474,7 +566,7 @@ export function version(attrs: Attributes): Attribute {
474
566
  }
475
567
  return undefined;
476
568
  }
477
- export function key(attrs: Attributes): Attribute {
569
+ export function key(attrs: Attributes): Attribute|undefined {
478
570
  const ks = Object.keys(attrs);
479
571
  for (const k of ks) {
480
572
  const attr = attrs[k];
@@ -483,7 +575,7 @@ export function key(attrs: Attributes): Attribute {
483
575
  return attr;
484
576
  }
485
577
  }
486
- return null;
578
+ return undefined;
487
579
  }
488
580
  export function keys(attrs: Attributes): Attribute[] {
489
581
  const ks = Object.keys(attrs);
@@ -503,7 +595,7 @@ export function buildMap(attrs: Attributes): StringMap {
503
595
  for (const k of ks) {
504
596
  const attr = attrs[k];
505
597
  attr.name = k;
506
- const field = (attr.field ? attr.field : k);
598
+ const field = (attr.column ? attr.column : k);
507
599
  const s = field.toLowerCase();
508
600
  if (s !== k) {
509
601
  mp[s] = k;
@@ -524,8 +616,8 @@ export function metadata(attrs: Attributes): Metadata {
524
616
  const ats: Attribute[] = [];
525
617
  const bools: Attribute[] = [];
526
618
  const fields: string[] = [];
527
- let ver: string;
528
619
  let isMap = false;
620
+ const m: Metadata = {keys: ats, fields};
529
621
  for (const k of ks) {
530
622
  const attr = attrs[k];
531
623
  attr.name = k;
@@ -539,16 +631,15 @@ export function metadata(attrs: Attributes): Metadata {
539
631
  bools.push(attr);
540
632
  }
541
633
  if (attr.version) {
542
- ver = k;
634
+ m.version = k;
543
635
  }
544
- const field = (attr.field ? attr.field : k);
636
+ const field = (attr.column ? attr.column : k);
545
637
  const s = field.toLowerCase();
546
638
  if (s !== k) {
547
639
  mp[s] = k;
548
640
  isMap = true;
549
641
  }
550
642
  }
551
- const m: Metadata = {keys: ats, fields, version: ver};
552
643
  if (isMap) {
553
644
  m.map = mp;
554
645
  }
@@ -560,7 +651,7 @@ export function metadata(attrs: Attributes): Metadata {
560
651
  export function attributes(attrs: string[], isKey?: boolean) {
561
652
  const ks: Attribute[] = [];
562
653
  for (const s of attrs) {
563
- const a: Attribute = {name: s, field: s, key: isKey};
654
+ const a: Attribute = {name: s, column: s, key: isKey};
564
655
  ks.push(a);
565
656
  }
566
657
  return ks;
@@ -570,7 +661,7 @@ export function param(i: number): string {
570
661
  }
571
662
  export function setValue<T, V>(obj: T, path: string, value: V): void {
572
663
  const paths = path.split('.');
573
- let o = obj;
664
+ let o: any = obj;
574
665
  for (let i = 0; i < paths.length - 1; i++) {
575
666
  const p = paths[i];
576
667
  if (p in o) {