@aws-amplify/datastore 3.7.3-webpack5.5 → 3.7.4-custom-pk.80
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/CHANGELOG.md +153 -15
- package/README.md +154 -0
- package/dist/aws-amplify-datastore.js +4638 -2685
- package/dist/aws-amplify-datastore.js.map +1 -1
- package/dist/aws-amplify-datastore.min.js +25 -95
- package/dist/aws-amplify-datastore.min.js.map +1 -1
- package/lib/authModeStrategies/multiAuthStrategy.d.ts +2 -2
- package/lib/authModeStrategies/multiAuthStrategy.js +32 -26
- package/lib/authModeStrategies/multiAuthStrategy.js.map +1 -1
- package/lib/datastore/datastore.d.ts +17 -16
- package/lib/datastore/datastore.js +249 -78
- package/lib/datastore/datastore.js.map +1 -1
- package/lib/index.d.ts +3 -19
- package/lib/predicates/index.d.ts +3 -2
- package/lib/predicates/index.js +12 -2
- package/lib/predicates/index.js.map +1 -1
- package/lib/storage/adapter/AsyncStorageAdapter.d.ts +6 -2
- package/lib/storage/adapter/AsyncStorageAdapter.js +140 -66
- package/lib/storage/adapter/AsyncStorageAdapter.js.map +1 -1
- package/lib/storage/adapter/AsyncStorageDatabase.d.ts +4 -4
- package/lib/storage/adapter/AsyncStorageDatabase.js +57 -27
- package/lib/storage/adapter/AsyncStorageDatabase.js.map +1 -1
- package/lib/storage/adapter/InMemoryStore.js +2 -2
- package/lib/storage/adapter/InMemoryStore.js.map +1 -1
- package/lib/storage/adapter/IndexedDBAdapter.d.ts +7 -2
- package/lib/storage/adapter/IndexedDBAdapter.js +454 -252
- package/lib/storage/adapter/IndexedDBAdapter.js.map +1 -1
- package/lib/storage/adapter/index.d.ts +1 -1
- package/lib/storage/storage.d.ts +3 -3
- package/lib/storage/storage.js +106 -28
- package/lib/storage/storage.js.map +1 -1
- package/lib/sync/index.d.ts +23 -7
- package/lib/sync/index.js +18 -17
- package/lib/sync/index.js.map +1 -1
- package/lib/sync/merger.d.ts +3 -3
- package/lib/sync/merger.js +8 -6
- package/lib/sync/merger.js.map +1 -1
- package/lib/sync/outbox.d.ts +2 -2
- package/lib/sync/outbox.js +12 -9
- package/lib/sync/outbox.js.map +1 -1
- package/lib/sync/processors/errorMaps.d.ts +17 -0
- package/lib/sync/processors/errorMaps.js +125 -0
- package/lib/sync/processors/errorMaps.js.map +1 -0
- package/lib/sync/processors/mutation.d.ts +22 -4
- package/lib/sync/processors/mutation.js +119 -51
- package/lib/sync/processors/mutation.js.map +1 -1
- package/lib/sync/processors/subscription.d.ts +4 -2
- package/lib/sync/processors/subscription.js +76 -41
- package/lib/sync/processors/subscription.js.map +1 -1
- package/lib/sync/processors/sync.d.ts +4 -2
- package/lib/sync/processors/sync.js +62 -27
- package/lib/sync/processors/sync.js.map +1 -1
- package/lib/sync/utils.d.ts +3 -2
- package/lib/sync/utils.js +58 -7
- package/lib/sync/utils.js.map +1 -1
- package/lib/types.d.ts +90 -34
- package/lib/types.js +31 -2
- package/lib/types.js.map +1 -1
- package/lib/util.d.ts +44 -33
- package/lib/util.js +210 -57
- package/lib/util.js.map +1 -1
- package/lib-esm/authModeStrategies/multiAuthStrategy.d.ts +2 -2
- package/lib-esm/authModeStrategies/multiAuthStrategy.js +32 -26
- package/lib-esm/authModeStrategies/multiAuthStrategy.js.map +1 -1
- package/lib-esm/datastore/datastore.d.ts +17 -16
- package/lib-esm/datastore/datastore.js +251 -80
- package/lib-esm/datastore/datastore.js.map +1 -1
- package/lib-esm/index.d.ts +3 -19
- package/lib-esm/predicates/index.d.ts +3 -2
- package/lib-esm/predicates/index.js +13 -3
- package/lib-esm/predicates/index.js.map +1 -1
- package/lib-esm/storage/adapter/AsyncStorageAdapter.d.ts +6 -2
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js +140 -66
- package/lib-esm/storage/adapter/AsyncStorageAdapter.js.map +1 -1
- package/lib-esm/storage/adapter/AsyncStorageDatabase.d.ts +4 -4
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js +57 -27
- package/lib-esm/storage/adapter/AsyncStorageDatabase.js.map +1 -1
- package/lib-esm/storage/adapter/InMemoryStore.js +2 -2
- package/lib-esm/storage/adapter/InMemoryStore.js.map +1 -1
- package/lib-esm/storage/adapter/IndexedDBAdapter.d.ts +7 -2
- package/lib-esm/storage/adapter/IndexedDBAdapter.js +454 -252
- package/lib-esm/storage/adapter/IndexedDBAdapter.js.map +1 -1
- package/lib-esm/storage/adapter/index.d.ts +1 -1
- package/lib-esm/storage/storage.d.ts +3 -3
- package/lib-esm/storage/storage.js +106 -28
- package/lib-esm/storage/storage.js.map +1 -1
- package/lib-esm/sync/index.d.ts +23 -7
- package/lib-esm/sync/index.js +20 -19
- package/lib-esm/sync/index.js.map +1 -1
- package/lib-esm/sync/merger.d.ts +3 -3
- package/lib-esm/sync/merger.js +8 -6
- package/lib-esm/sync/merger.js.map +1 -1
- package/lib-esm/sync/outbox.d.ts +2 -2
- package/lib-esm/sync/outbox.js +13 -10
- package/lib-esm/sync/outbox.js.map +1 -1
- package/lib-esm/sync/processors/errorMaps.d.ts +17 -0
- package/lib-esm/sync/processors/errorMaps.js +119 -0
- package/lib-esm/sync/processors/errorMaps.js.map +1 -0
- package/lib-esm/sync/processors/mutation.d.ts +22 -4
- package/lib-esm/sync/processors/mutation.js +122 -54
- package/lib-esm/sync/processors/mutation.js.map +1 -1
- package/lib-esm/sync/processors/subscription.d.ts +4 -2
- package/lib-esm/sync/processors/subscription.js +77 -42
- package/lib-esm/sync/processors/subscription.js.map +1 -1
- package/lib-esm/sync/processors/sync.d.ts +4 -2
- package/lib-esm/sync/processors/sync.js +62 -27
- package/lib-esm/sync/processors/sync.js.map +1 -1
- package/lib-esm/sync/utils.d.ts +3 -2
- package/lib-esm/sync/utils.js +58 -8
- package/lib-esm/sync/utils.js.map +1 -1
- package/lib-esm/types.d.ts +90 -34
- package/lib-esm/types.js +29 -3
- package/lib-esm/types.js.map +1 -1
- package/lib-esm/util.d.ts +44 -33
- package/lib-esm/util.js +199 -54
- package/lib-esm/util.js.map +1 -1
- package/package.json +10 -9
- package/src/authModeStrategies/multiAuthStrategy.ts +24 -21
- package/src/datastore/datastore.ts +395 -143
- package/src/predicates/index.ts +32 -10
- package/src/storage/adapter/AsyncStorageAdapter.ts +161 -61
- package/src/storage/adapter/AsyncStorageDatabase.ts +62 -25
- package/src/storage/adapter/InMemoryStore.ts +2 -2
- package/src/storage/adapter/IndexedDBAdapter.ts +345 -101
- package/src/storage/adapter/index.ts +1 -1
- package/src/storage/storage.ts +85 -24
- package/src/sync/index.ts +74 -58
- package/src/sync/merger.ts +16 -4
- package/src/sync/outbox.ts +22 -8
- package/src/sync/processors/errorMaps.ts +93 -0
- package/src/sync/processors/mutation.ts +143 -84
- package/src/sync/processors/subscription.ts +67 -36
- package/src/sync/processors/sync.ts +37 -12
- package/src/sync/utils.ts +67 -16
- package/src/types.ts +252 -50
- package/src/util.ts +241 -42
- package/ssr/package.json +1 -1
package/src/util.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Buffer } from 'buffer';
|
|
2
2
|
import { monotonicFactory, ULID } from 'ulid';
|
|
3
3
|
import { v4 as uuid } from 'uuid';
|
|
4
|
+
import { produce, applyPatches, Patch } from 'immer';
|
|
4
5
|
import { ModelInstanceCreator } from './datastore/datastore';
|
|
5
6
|
import {
|
|
6
7
|
AllOperators,
|
|
@@ -25,8 +26,81 @@ import {
|
|
|
25
26
|
NonModelTypeConstructor,
|
|
26
27
|
DeferredCallbackResolverOptions,
|
|
27
28
|
LimitTimerRaceResolvedValues,
|
|
29
|
+
SchemaModel,
|
|
30
|
+
ModelAttribute,
|
|
31
|
+
IndexesType,
|
|
28
32
|
} from './types';
|
|
29
33
|
import { WordArray } from 'amazon-cognito-identity-js';
|
|
34
|
+
const ID = 'id';
|
|
35
|
+
|
|
36
|
+
export function extractKeyIfExists(
|
|
37
|
+
modelDefinition: SchemaModel
|
|
38
|
+
): ModelAttribute | undefined {
|
|
39
|
+
const keyAttribute = modelDefinition?.attributes?.find(isModelAttributeKey);
|
|
40
|
+
|
|
41
|
+
return keyAttribute;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function extractPrimaryKeyFieldNames(
|
|
45
|
+
modelDefinition: SchemaModel
|
|
46
|
+
): string[] {
|
|
47
|
+
const keyAttribute = extractKeyIfExists(modelDefinition);
|
|
48
|
+
if (keyAttribute && isModelAttributePrimaryKey(keyAttribute)) {
|
|
49
|
+
return keyAttribute.properties.fields;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return [ID];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function extractPrimaryKeyValues<T extends PersistentModel>(
|
|
56
|
+
model: T,
|
|
57
|
+
keyFields: string[]
|
|
58
|
+
): string[] {
|
|
59
|
+
return keyFields.map(key => model[key]);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// IdentifierFields<ManagedIdentifier>
|
|
63
|
+
// Default behavior without explicit @primaryKey defined
|
|
64
|
+
export function isIdManaged(modelDefinition: SchemaModel): boolean {
|
|
65
|
+
const keyAttribute = extractKeyIfExists(modelDefinition);
|
|
66
|
+
|
|
67
|
+
if (keyAttribute && isModelAttributePrimaryKey(keyAttribute)) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// IdentifierFields<OptionallyManagedIdentifier>
|
|
75
|
+
// @primaryKey with explicit `id` in the PK. Single key or composite
|
|
76
|
+
export function isIdOptionallyManaged(modelDefinition: SchemaModel): boolean {
|
|
77
|
+
const keyAttribute = extractKeyIfExists(modelDefinition);
|
|
78
|
+
|
|
79
|
+
if (keyAttribute && isModelAttributePrimaryKey(keyAttribute)) {
|
|
80
|
+
// const idInKey = !!keyAttribute.properties.fields.find(
|
|
81
|
+
// field => field === ID
|
|
82
|
+
// );
|
|
83
|
+
// return idInKey && keyAttribute.properties.fields.length === 1;
|
|
84
|
+
return keyAttribute.properties.fields[0] === ID;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export enum NAMESPACES {
|
|
91
|
+
DATASTORE = 'datastore',
|
|
92
|
+
USER = 'user',
|
|
93
|
+
SYNC = 'sync',
|
|
94
|
+
STORAGE = 'storage',
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const DATASTORE = NAMESPACES.DATASTORE;
|
|
98
|
+
const USER = NAMESPACES.USER;
|
|
99
|
+
const SYNC = NAMESPACES.SYNC;
|
|
100
|
+
const STORAGE = NAMESPACES.STORAGE;
|
|
101
|
+
|
|
102
|
+
export { USER, SYNC, STORAGE, DATASTORE };
|
|
103
|
+
export const USER_AGENT_SUFFIX_DATASTORE = '/DataStore';
|
|
30
104
|
|
|
31
105
|
export const exhaustiveCheck = (obj: never, throwOnError: boolean = true) => {
|
|
32
106
|
if (throwOnError) {
|
|
@@ -146,7 +220,7 @@ export const isNonModelConstructor = (
|
|
|
146
220
|
return nonModelClasses.has(obj);
|
|
147
221
|
};
|
|
148
222
|
|
|
149
|
-
/*
|
|
223
|
+
/*
|
|
150
224
|
When we have GSI(s) with composite sort keys defined on a model
|
|
151
225
|
There are some very particular rules regarding which fields must be included in the update mutation input
|
|
152
226
|
The field selection becomes more complex as the number of GSIs with composite sort keys grows
|
|
@@ -156,7 +230,7 @@ export const isNonModelConstructor = (
|
|
|
156
230
|
2. all of the fields from any other composite sort key that intersect with the fields from 1.
|
|
157
231
|
|
|
158
232
|
E.g.,
|
|
159
|
-
Model @model
|
|
233
|
+
Model @model
|
|
160
234
|
@key(name: 'key1' fields: ['hk', 'a', 'b', 'c'])
|
|
161
235
|
@key(name: 'key2' fields: ['hk', 'a', 'b', 'd'])
|
|
162
236
|
@key(name: 'key3' fields: ['hk', 'x', 'y', 'z'])
|
|
@@ -192,7 +266,7 @@ export const processCompositeKeys = (
|
|
|
192
266
|
.filter(isModelAttributeCompositeKey)
|
|
193
267
|
.map(extractCompositeSortKey);
|
|
194
268
|
|
|
195
|
-
/*
|
|
269
|
+
/*
|
|
196
270
|
if 2 sets of fields have any intersecting fields => combine them into 1 union set
|
|
197
271
|
e.g., ['a', 'b', 'c'] and ['a', 'b', 'd'] => ['a', 'b', 'c', 'd']
|
|
198
272
|
*/
|
|
@@ -256,13 +330,19 @@ export const establishRelationAndKeys = (
|
|
|
256
330
|
modelName: fieldAttribute.type.model,
|
|
257
331
|
relationType: connectionType,
|
|
258
332
|
targetName: fieldAttribute.association['targetName'],
|
|
333
|
+
targetNames: fieldAttribute.association['targetNames'],
|
|
259
334
|
associatedWith: fieldAttribute.association['associatedWith'],
|
|
260
335
|
});
|
|
261
336
|
|
|
262
337
|
if (connectionType === 'BELONGS_TO') {
|
|
263
|
-
|
|
264
|
-
fieldAttribute.association
|
|
338
|
+
const targetNames = extractTargetNamesFromSrc(
|
|
339
|
+
fieldAttribute.association
|
|
265
340
|
);
|
|
341
|
+
|
|
342
|
+
if (targetNames) {
|
|
343
|
+
const idxName = indexNameFromKeys(targetNames);
|
|
344
|
+
relationship[mKey].indexes.push([idxName, targetNames]);
|
|
345
|
+
}
|
|
266
346
|
}
|
|
267
347
|
}
|
|
268
348
|
});
|
|
@@ -275,20 +355,36 @@ export const establishRelationAndKeys = (
|
|
|
275
355
|
continue;
|
|
276
356
|
}
|
|
277
357
|
|
|
358
|
+
const { fields } = attribute.properties;
|
|
359
|
+
|
|
278
360
|
if (isModelAttributePrimaryKey(attribute)) {
|
|
279
|
-
keys[mKey].primaryKey =
|
|
361
|
+
keys[mKey].primaryKey = fields;
|
|
362
|
+
continue;
|
|
280
363
|
}
|
|
281
364
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
365
|
+
// create indexes for all other keys
|
|
366
|
+
const idxName = indexNameFromKeys(fields);
|
|
367
|
+
const idxExists = relationship[mKey].indexes.find(
|
|
368
|
+
([index]) => index === idxName
|
|
369
|
+
);
|
|
370
|
+
|
|
371
|
+
if (!idxExists) {
|
|
372
|
+
relationship[mKey].indexes.push([idxName, fields]);
|
|
289
373
|
}
|
|
290
374
|
}
|
|
291
375
|
}
|
|
376
|
+
|
|
377
|
+
// set 'id' as the PK for models without a custom PK explicitly defined
|
|
378
|
+
if (!keys[mKey].primaryKey) {
|
|
379
|
+
keys[mKey].primaryKey = [ID];
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// create primary index
|
|
383
|
+
relationship[mKey].indexes.push([
|
|
384
|
+
'byPk',
|
|
385
|
+
keys[mKey].primaryKey as string[],
|
|
386
|
+
{ unique: true },
|
|
387
|
+
]);
|
|
292
388
|
});
|
|
293
389
|
|
|
294
390
|
return [relationship, keys];
|
|
@@ -307,12 +403,14 @@ export const traverseModel = <T extends PersistentModel>(
|
|
|
307
403
|
) => PersistentModelConstructor<any>
|
|
308
404
|
) => {
|
|
309
405
|
const relationships = namespace.relationships;
|
|
406
|
+
|
|
310
407
|
const modelConstructor = getModelConstructorByModelName(
|
|
311
408
|
namespace.name,
|
|
312
409
|
srcModelName
|
|
313
410
|
);
|
|
314
411
|
|
|
315
412
|
const relation = relationships[srcModelName];
|
|
413
|
+
|
|
316
414
|
const result: {
|
|
317
415
|
modelName: string;
|
|
318
416
|
item: T;
|
|
@@ -346,15 +444,36 @@ export const traverseModel = <T extends PersistentModel>(
|
|
|
346
444
|
instance: modelInstance,
|
|
347
445
|
});
|
|
348
446
|
|
|
349
|
-
|
|
447
|
+
const targetNames: string[] | undefined =
|
|
448
|
+
extractTargetNamesFromSrc(rItem);
|
|
449
|
+
|
|
450
|
+
// `targetName` will be defined for Has One if feature flag
|
|
350
451
|
// https://docs.amplify.aws/cli/reference/feature-flags/#useAppsyncModelgenPlugin
|
|
351
452
|
// is true (default as of 5/7/21)
|
|
352
453
|
// Making this conditional for backward-compatibility
|
|
353
|
-
if (
|
|
354
|
-
(
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
454
|
+
if (targetNames) {
|
|
455
|
+
targetNames.forEach((targetName, idx) => {
|
|
456
|
+
// Get the connected record
|
|
457
|
+
const relatedRecordInProxy = <PersistentModel>(
|
|
458
|
+
draftInstance[rItem.fieldName]
|
|
459
|
+
);
|
|
460
|
+
|
|
461
|
+
// Previously, we used the hardcoded 'id' as they key,
|
|
462
|
+
// now we need the value of the key to get the PK (and SK)
|
|
463
|
+
// values from the related record
|
|
464
|
+
|
|
465
|
+
const { primaryKey } = namespace.keys[modelConstructor.name];
|
|
466
|
+
const keyField = primaryKey && primaryKey[idx];
|
|
467
|
+
|
|
468
|
+
// Get the value
|
|
469
|
+
const relatedRecordInProxyPkValue =
|
|
470
|
+
relatedRecordInProxy[keyField];
|
|
471
|
+
|
|
472
|
+
// Set the targetName value
|
|
473
|
+
(<any>draftInstance)[targetName] = relatedRecordInProxyPkValue;
|
|
474
|
+
});
|
|
475
|
+
// Delete the instance from the proxy
|
|
476
|
+
delete (<any>draftInstance)[rItem.fieldName];
|
|
358
477
|
} else {
|
|
359
478
|
(<any>draftInstance)[rItem.fieldName] = (<PersistentModel>(
|
|
360
479
|
draftInstance[rItem.fieldName]
|
|
@@ -389,10 +508,33 @@ export const traverseModel = <T extends PersistentModel>(
|
|
|
389
508
|
}
|
|
390
509
|
|
|
391
510
|
if (draftInstance[rItem.fieldName]) {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
511
|
+
const targetNames: string[] | undefined =
|
|
512
|
+
extractTargetNamesFromSrc(rItem);
|
|
513
|
+
|
|
514
|
+
if (targetNames) {
|
|
515
|
+
targetNames.forEach((targetName, idx) => {
|
|
516
|
+
// Get the connected record
|
|
517
|
+
const relatedRecordInProxy = <PersistentModel>(
|
|
518
|
+
draftInstance[rItem.fieldName]
|
|
519
|
+
);
|
|
520
|
+
// Previously, we used the hardcoded `id` for the key.
|
|
521
|
+
// Now, we need the value of the key to get the PK (and SK)
|
|
522
|
+
// values from the related record
|
|
523
|
+
const { primaryKey } = namespace.keys[modelConstructor.name];
|
|
524
|
+
|
|
525
|
+
// fall back to ID if
|
|
526
|
+
const keyField = primaryKey && primaryKey[idx];
|
|
527
|
+
|
|
528
|
+
// Get the value
|
|
529
|
+
const relatedRecordInProxyPkValue =
|
|
530
|
+
relatedRecordInProxy[keyField];
|
|
531
|
+
|
|
532
|
+
// Set the targetName value
|
|
533
|
+
(<any>draftInstance)[targetName] = relatedRecordInProxyPkValue;
|
|
534
|
+
});
|
|
535
|
+
// Delete the instance from the proxy
|
|
536
|
+
delete (<any>draftInstance)[rItem.fieldName];
|
|
537
|
+
}
|
|
396
538
|
}
|
|
397
539
|
|
|
398
540
|
break;
|
|
@@ -430,7 +572,7 @@ export const traverseModel = <T extends PersistentModel>(
|
|
|
430
572
|
return result;
|
|
431
573
|
};
|
|
432
574
|
|
|
433
|
-
export const getIndex = (rel: RelationType[], src:
|
|
575
|
+
export const getIndex = (rel: RelationType[], src: any): string | undefined => {
|
|
434
576
|
let index = '';
|
|
435
577
|
rel.some((relItem: RelationType) => {
|
|
436
578
|
if (relItem.modelName === src) {
|
|
@@ -441,26 +583,20 @@ export const getIndex = (rel: RelationType[], src: string): string => {
|
|
|
441
583
|
};
|
|
442
584
|
|
|
443
585
|
export const getIndexFromAssociation = (
|
|
444
|
-
indexes:
|
|
445
|
-
src: string
|
|
446
|
-
): string => {
|
|
447
|
-
|
|
448
|
-
return index;
|
|
449
|
-
};
|
|
586
|
+
indexes: IndexesType,
|
|
587
|
+
src: string | string[]
|
|
588
|
+
): string | undefined => {
|
|
589
|
+
let indexName: string;
|
|
450
590
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
const DATASTORE = NAMESPACES.DATASTORE;
|
|
459
|
-
const USER = NAMESPACES.USER;
|
|
460
|
-
const SYNC = NAMESPACES.SYNC;
|
|
461
|
-
const STORAGE = NAMESPACES.STORAGE;
|
|
591
|
+
if (Array.isArray(src)) {
|
|
592
|
+
indexName = indexNameFromKeys(src);
|
|
593
|
+
} else {
|
|
594
|
+
indexName = src;
|
|
595
|
+
}
|
|
462
596
|
|
|
463
|
-
|
|
597
|
+
const associationIndex = indexes.find(([idxName]) => idxName === indexName);
|
|
598
|
+
return associationIndex && associationIndex[0];
|
|
599
|
+
};
|
|
464
600
|
|
|
465
601
|
let privateModeCheckResult;
|
|
466
602
|
|
|
@@ -773,3 +909,66 @@ export class DeferredCallbackResolver {
|
|
|
773
909
|
this.limitPromise.resolve(LimitTimerRaceResolvedValues.LIMIT);
|
|
774
910
|
}
|
|
775
911
|
}
|
|
912
|
+
|
|
913
|
+
/**
|
|
914
|
+
* merge two sets of patches created by immer produce.
|
|
915
|
+
* newPatches take precedent over oldPatches for patches modifying the same path.
|
|
916
|
+
* In the case many consecutive pathces are merged the original model should
|
|
917
|
+
* always be the root model.
|
|
918
|
+
*
|
|
919
|
+
* Example:
|
|
920
|
+
* A -> B, patches1
|
|
921
|
+
* B -> C, patches2
|
|
922
|
+
*
|
|
923
|
+
* mergePatches(A, patches1, patches2) to get patches for A -> C
|
|
924
|
+
*
|
|
925
|
+
* @param originalSource the original Model the patches should be applied to
|
|
926
|
+
* @param oldPatches immer produce patch list
|
|
927
|
+
* @param newPatches immer produce patch list (will take precedence)
|
|
928
|
+
* @return merged patches
|
|
929
|
+
*/
|
|
930
|
+
export function mergePatches<T>(
|
|
931
|
+
originalSource: T,
|
|
932
|
+
oldPatches: Patch[],
|
|
933
|
+
newPatches: Patch[]
|
|
934
|
+
): Patch[] {
|
|
935
|
+
const patchesToMerge = oldPatches.concat(newPatches);
|
|
936
|
+
let patches: Patch[];
|
|
937
|
+
produce(
|
|
938
|
+
originalSource,
|
|
939
|
+
draft => {
|
|
940
|
+
applyPatches(draft, patchesToMerge);
|
|
941
|
+
},
|
|
942
|
+
p => {
|
|
943
|
+
patches = p;
|
|
944
|
+
}
|
|
945
|
+
);
|
|
946
|
+
return patches;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
/* Backwards-compatability for schema generated prior to custom primary key support:
|
|
950
|
+
the single field `targetName` has been replaced with an array of `targetNames`
|
|
951
|
+
*/
|
|
952
|
+
export function extractTargetNamesFromSrc(src: any): string[] | undefined {
|
|
953
|
+
const targetName = src?.targetName;
|
|
954
|
+
const targetNames = src?.targetNames;
|
|
955
|
+
|
|
956
|
+
if (Array.isArray(targetNames) && targetNames?.length) {
|
|
957
|
+
return targetNames;
|
|
958
|
+
} else if (typeof targetName === 'string') {
|
|
959
|
+
return [targetName];
|
|
960
|
+
} else {
|
|
961
|
+
return undefined;
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
// Generates snake-cased index name from an aray of key field names
|
|
966
|
+
// E.g. for keys `[id, title]` => 'id-title'
|
|
967
|
+
export function indexNameFromKeys(keys: string[]): string {
|
|
968
|
+
return keys.reduce((prev: string, cur: string, idx: number) => {
|
|
969
|
+
if (idx === 0) {
|
|
970
|
+
return cur;
|
|
971
|
+
}
|
|
972
|
+
return `${prev}-${cur}`;
|
|
973
|
+
}, '');
|
|
974
|
+
}
|
package/ssr/package.json
CHANGED