@aws-amplify/datastore 3.7.3 → 3.7.4-custom-pk.86
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 +144 -17
- package/README.md +154 -0
- package/dist/aws-amplify-datastore.js +3740 -1599
- 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 +291 -83
- 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 +361 -193
- package/lib/storage/adapter/AsyncStorageAdapter.js.map +1 -1
- package/lib/storage/adapter/AsyncStorageDatabase.d.ts +4 -4
- package/lib/storage/adapter/AsyncStorageDatabase.js +59 -28
- 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 +48 -33
- package/lib/util.js +219 -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 +293 -85
- 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 +361 -193
- 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 +60 -29
- 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 +48 -33
- package/lib-esm/util.js +207 -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 +448 -148
- package/src/predicates/index.ts +32 -10
- package/src/storage/adapter/AsyncStorageAdapter.ts +305 -78
- package/src/storage/adapter/AsyncStorageDatabase.ts +65 -26
- package/src/storage/adapter/InMemoryStore.ts +2 -2
- package/src/storage/adapter/IndexedDBAdapter.ts +344 -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 +256 -42
- package/ssr/package.json +1 -1
package/src/util.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
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,
|
|
8
|
+
ProducerModelPredicate,
|
|
7
9
|
isPredicateGroup,
|
|
8
10
|
isPredicateObj,
|
|
9
11
|
ModelInstanceMetadata,
|
|
@@ -25,9 +27,96 @@ import {
|
|
|
25
27
|
NonModelTypeConstructor,
|
|
26
28
|
DeferredCallbackResolverOptions,
|
|
27
29
|
LimitTimerRaceResolvedValues,
|
|
30
|
+
SchemaModel,
|
|
31
|
+
ModelAttribute,
|
|
32
|
+
IndexesType,
|
|
28
33
|
} from './types';
|
|
29
34
|
import { WordArray } from 'amazon-cognito-identity-js';
|
|
30
35
|
|
|
36
|
+
const ID = 'id';
|
|
37
|
+
|
|
38
|
+
export const errorMessages = {
|
|
39
|
+
idEmptyString: 'An index field cannot contain an empty string value',
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export function extractKeyIfExists(
|
|
43
|
+
modelDefinition: SchemaModel
|
|
44
|
+
): ModelAttribute | undefined {
|
|
45
|
+
const keyAttribute = modelDefinition?.attributes?.find(isModelAttributeKey);
|
|
46
|
+
|
|
47
|
+
return keyAttribute;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function extractPrimaryKeyFieldNames(
|
|
51
|
+
modelDefinition: SchemaModel
|
|
52
|
+
): string[] {
|
|
53
|
+
const keyAttribute = extractKeyIfExists(modelDefinition);
|
|
54
|
+
if (keyAttribute && isModelAttributePrimaryKey(keyAttribute)) {
|
|
55
|
+
return keyAttribute.properties.fields;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return [ID];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function extractPrimaryKeyValues<T extends PersistentModel>(
|
|
62
|
+
model: T,
|
|
63
|
+
keyFields: string[]
|
|
64
|
+
): string[] {
|
|
65
|
+
return keyFields.map(key => model[key]);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function extractPrimaryKeysAndValues<T extends PersistentModel>(
|
|
69
|
+
model: T,
|
|
70
|
+
keyFields: string[]
|
|
71
|
+
): any {
|
|
72
|
+
const primaryKeysAndValues = {};
|
|
73
|
+
keyFields.forEach(key => (primaryKeysAndValues[key] = model[key]));
|
|
74
|
+
return primaryKeysAndValues;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// IdentifierFields<ManagedIdentifier>
|
|
78
|
+
// Default behavior without explicit @primaryKey defined
|
|
79
|
+
export function isIdManaged(modelDefinition: SchemaModel): boolean {
|
|
80
|
+
const keyAttribute = extractKeyIfExists(modelDefinition);
|
|
81
|
+
|
|
82
|
+
if (keyAttribute && isModelAttributePrimaryKey(keyAttribute)) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// IdentifierFields<OptionallyManagedIdentifier>
|
|
90
|
+
// @primaryKey with explicit `id` in the PK. Single key or composite
|
|
91
|
+
export function isIdOptionallyManaged(modelDefinition: SchemaModel): boolean {
|
|
92
|
+
const keyAttribute = extractKeyIfExists(modelDefinition);
|
|
93
|
+
|
|
94
|
+
if (keyAttribute && isModelAttributePrimaryKey(keyAttribute)) {
|
|
95
|
+
// const idInKey = !!keyAttribute.properties.fields.find(
|
|
96
|
+
// field => field === ID
|
|
97
|
+
// );
|
|
98
|
+
// return idInKey && keyAttribute.properties.fields.length === 1;
|
|
99
|
+
return keyAttribute.properties.fields[0] === ID;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export enum NAMESPACES {
|
|
106
|
+
DATASTORE = 'datastore',
|
|
107
|
+
USER = 'user',
|
|
108
|
+
SYNC = 'sync',
|
|
109
|
+
STORAGE = 'storage',
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const DATASTORE = NAMESPACES.DATASTORE;
|
|
113
|
+
const USER = NAMESPACES.USER;
|
|
114
|
+
const SYNC = NAMESPACES.SYNC;
|
|
115
|
+
const STORAGE = NAMESPACES.STORAGE;
|
|
116
|
+
|
|
117
|
+
export { USER, SYNC, STORAGE, DATASTORE };
|
|
118
|
+
export const USER_AGENT_SUFFIX_DATASTORE = '/DataStore';
|
|
119
|
+
|
|
31
120
|
export const exhaustiveCheck = (obj: never, throwOnError: boolean = true) => {
|
|
32
121
|
if (throwOnError) {
|
|
33
122
|
throw new Error(`Invalid ${obj}`);
|
|
@@ -146,7 +235,7 @@ export const isNonModelConstructor = (
|
|
|
146
235
|
return nonModelClasses.has(obj);
|
|
147
236
|
};
|
|
148
237
|
|
|
149
|
-
/*
|
|
238
|
+
/*
|
|
150
239
|
When we have GSI(s) with composite sort keys defined on a model
|
|
151
240
|
There are some very particular rules regarding which fields must be included in the update mutation input
|
|
152
241
|
The field selection becomes more complex as the number of GSIs with composite sort keys grows
|
|
@@ -156,7 +245,7 @@ export const isNonModelConstructor = (
|
|
|
156
245
|
2. all of the fields from any other composite sort key that intersect with the fields from 1.
|
|
157
246
|
|
|
158
247
|
E.g.,
|
|
159
|
-
Model @model
|
|
248
|
+
Model @model
|
|
160
249
|
@key(name: 'key1' fields: ['hk', 'a', 'b', 'c'])
|
|
161
250
|
@key(name: 'key2' fields: ['hk', 'a', 'b', 'd'])
|
|
162
251
|
@key(name: 'key3' fields: ['hk', 'x', 'y', 'z'])
|
|
@@ -192,7 +281,7 @@ export const processCompositeKeys = (
|
|
|
192
281
|
.filter(isModelAttributeCompositeKey)
|
|
193
282
|
.map(extractCompositeSortKey);
|
|
194
283
|
|
|
195
|
-
/*
|
|
284
|
+
/*
|
|
196
285
|
if 2 sets of fields have any intersecting fields => combine them into 1 union set
|
|
197
286
|
e.g., ['a', 'b', 'c'] and ['a', 'b', 'd'] => ['a', 'b', 'c', 'd']
|
|
198
287
|
*/
|
|
@@ -256,13 +345,19 @@ export const establishRelationAndKeys = (
|
|
|
256
345
|
modelName: fieldAttribute.type.model,
|
|
257
346
|
relationType: connectionType,
|
|
258
347
|
targetName: fieldAttribute.association['targetName'],
|
|
348
|
+
targetNames: fieldAttribute.association['targetNames'],
|
|
259
349
|
associatedWith: fieldAttribute.association['associatedWith'],
|
|
260
350
|
});
|
|
261
351
|
|
|
262
352
|
if (connectionType === 'BELONGS_TO') {
|
|
263
|
-
|
|
264
|
-
fieldAttribute.association
|
|
353
|
+
const targetNames = extractTargetNamesFromSrc(
|
|
354
|
+
fieldAttribute.association
|
|
265
355
|
);
|
|
356
|
+
|
|
357
|
+
if (targetNames) {
|
|
358
|
+
const idxName = indexNameFromKeys(targetNames);
|
|
359
|
+
relationship[mKey].indexes.push([idxName, targetNames]);
|
|
360
|
+
}
|
|
266
361
|
}
|
|
267
362
|
}
|
|
268
363
|
});
|
|
@@ -275,20 +370,36 @@ export const establishRelationAndKeys = (
|
|
|
275
370
|
continue;
|
|
276
371
|
}
|
|
277
372
|
|
|
373
|
+
const { fields } = attribute.properties;
|
|
374
|
+
|
|
278
375
|
if (isModelAttributePrimaryKey(attribute)) {
|
|
279
|
-
keys[mKey].primaryKey =
|
|
376
|
+
keys[mKey].primaryKey = fields;
|
|
377
|
+
continue;
|
|
280
378
|
}
|
|
281
379
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
380
|
+
// create indexes for all other keys
|
|
381
|
+
const idxName = indexNameFromKeys(fields);
|
|
382
|
+
const idxExists = relationship[mKey].indexes.find(
|
|
383
|
+
([index]) => index === idxName
|
|
384
|
+
);
|
|
385
|
+
|
|
386
|
+
if (!idxExists) {
|
|
387
|
+
relationship[mKey].indexes.push([idxName, fields]);
|
|
289
388
|
}
|
|
290
389
|
}
|
|
291
390
|
}
|
|
391
|
+
|
|
392
|
+
// set 'id' as the PK for models without a custom PK explicitly defined
|
|
393
|
+
if (!keys[mKey].primaryKey) {
|
|
394
|
+
keys[mKey].primaryKey = [ID];
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// create primary index
|
|
398
|
+
relationship[mKey].indexes.push([
|
|
399
|
+
'byPk',
|
|
400
|
+
keys[mKey].primaryKey as string[],
|
|
401
|
+
{ unique: true },
|
|
402
|
+
]);
|
|
292
403
|
});
|
|
293
404
|
|
|
294
405
|
return [relationship, keys];
|
|
@@ -307,12 +418,14 @@ export const traverseModel = <T extends PersistentModel>(
|
|
|
307
418
|
) => PersistentModelConstructor<any>
|
|
308
419
|
) => {
|
|
309
420
|
const relationships = namespace.relationships;
|
|
421
|
+
|
|
310
422
|
const modelConstructor = getModelConstructorByModelName(
|
|
311
423
|
namespace.name,
|
|
312
424
|
srcModelName
|
|
313
425
|
);
|
|
314
426
|
|
|
315
427
|
const relation = relationships[srcModelName];
|
|
428
|
+
|
|
316
429
|
const result: {
|
|
317
430
|
modelName: string;
|
|
318
431
|
item: T;
|
|
@@ -346,15 +459,36 @@ export const traverseModel = <T extends PersistentModel>(
|
|
|
346
459
|
instance: modelInstance,
|
|
347
460
|
});
|
|
348
461
|
|
|
349
|
-
|
|
462
|
+
const targetNames: string[] | undefined =
|
|
463
|
+
extractTargetNamesFromSrc(rItem);
|
|
464
|
+
|
|
465
|
+
// `targetName` will be defined for Has One if feature flag
|
|
350
466
|
// https://docs.amplify.aws/cli/reference/feature-flags/#useAppsyncModelgenPlugin
|
|
351
467
|
// is true (default as of 5/7/21)
|
|
352
468
|
// Making this conditional for backward-compatibility
|
|
353
|
-
if (
|
|
354
|
-
(
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
469
|
+
if (targetNames) {
|
|
470
|
+
targetNames.forEach((targetName, idx) => {
|
|
471
|
+
// Get the connected record
|
|
472
|
+
const relatedRecordInProxy = <PersistentModel>(
|
|
473
|
+
draftInstance[rItem.fieldName]
|
|
474
|
+
);
|
|
475
|
+
|
|
476
|
+
// Previously, we used the hardcoded 'id' as they key,
|
|
477
|
+
// now we need the value of the key to get the PK (and SK)
|
|
478
|
+
// values from the related record
|
|
479
|
+
|
|
480
|
+
const { primaryKey } = namespace.keys[modelConstructor.name];
|
|
481
|
+
const keyField = primaryKey && primaryKey[idx];
|
|
482
|
+
|
|
483
|
+
// Get the value
|
|
484
|
+
const relatedRecordInProxyPkValue =
|
|
485
|
+
relatedRecordInProxy[keyField];
|
|
486
|
+
|
|
487
|
+
// Set the targetName value
|
|
488
|
+
(<any>draftInstance)[targetName] = relatedRecordInProxyPkValue;
|
|
489
|
+
});
|
|
490
|
+
// Delete the instance from the proxy
|
|
491
|
+
delete (<any>draftInstance)[rItem.fieldName];
|
|
358
492
|
} else {
|
|
359
493
|
(<any>draftInstance)[rItem.fieldName] = (<PersistentModel>(
|
|
360
494
|
draftInstance[rItem.fieldName]
|
|
@@ -389,10 +523,33 @@ export const traverseModel = <T extends PersistentModel>(
|
|
|
389
523
|
}
|
|
390
524
|
|
|
391
525
|
if (draftInstance[rItem.fieldName]) {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
526
|
+
const targetNames: string[] | undefined =
|
|
527
|
+
extractTargetNamesFromSrc(rItem);
|
|
528
|
+
|
|
529
|
+
if (targetNames) {
|
|
530
|
+
targetNames.forEach((targetName, idx) => {
|
|
531
|
+
// Get the connected record
|
|
532
|
+
const relatedRecordInProxy = <PersistentModel>(
|
|
533
|
+
draftInstance[rItem.fieldName]
|
|
534
|
+
);
|
|
535
|
+
// Previously, we used the hardcoded `id` for the key.
|
|
536
|
+
// Now, we need the value of the key to get the PK (and SK)
|
|
537
|
+
// values from the related record
|
|
538
|
+
const { primaryKey } = namespace.keys[modelConstructor.name];
|
|
539
|
+
|
|
540
|
+
// fall back to ID if
|
|
541
|
+
const keyField = primaryKey && primaryKey[idx];
|
|
542
|
+
|
|
543
|
+
// Get the value
|
|
544
|
+
const relatedRecordInProxyPkValue =
|
|
545
|
+
relatedRecordInProxy[keyField];
|
|
546
|
+
|
|
547
|
+
// Set the targetName value
|
|
548
|
+
(<any>draftInstance)[targetName] = relatedRecordInProxyPkValue;
|
|
549
|
+
});
|
|
550
|
+
// Delete the instance from the proxy
|
|
551
|
+
delete (<any>draftInstance)[rItem.fieldName];
|
|
552
|
+
}
|
|
396
553
|
}
|
|
397
554
|
|
|
398
555
|
break;
|
|
@@ -430,7 +587,7 @@ export const traverseModel = <T extends PersistentModel>(
|
|
|
430
587
|
return result;
|
|
431
588
|
};
|
|
432
589
|
|
|
433
|
-
export const getIndex = (rel: RelationType[], src:
|
|
590
|
+
export const getIndex = (rel: RelationType[], src: any): string | undefined => {
|
|
434
591
|
let index = '';
|
|
435
592
|
rel.some((relItem: RelationType) => {
|
|
436
593
|
if (relItem.modelName === src) {
|
|
@@ -441,26 +598,20 @@ export const getIndex = (rel: RelationType[], src: string): string => {
|
|
|
441
598
|
};
|
|
442
599
|
|
|
443
600
|
export const getIndexFromAssociation = (
|
|
444
|
-
indexes:
|
|
445
|
-
src: string
|
|
446
|
-
): string => {
|
|
447
|
-
|
|
448
|
-
return index;
|
|
449
|
-
};
|
|
450
|
-
|
|
451
|
-
export enum NAMESPACES {
|
|
452
|
-
DATASTORE = 'datastore',
|
|
453
|
-
USER = 'user',
|
|
454
|
-
SYNC = 'sync',
|
|
455
|
-
STORAGE = 'storage',
|
|
456
|
-
}
|
|
601
|
+
indexes: IndexesType,
|
|
602
|
+
src: string | string[]
|
|
603
|
+
): string | undefined => {
|
|
604
|
+
let indexName: string;
|
|
457
605
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
606
|
+
if (Array.isArray(src)) {
|
|
607
|
+
indexName = indexNameFromKeys(src);
|
|
608
|
+
} else {
|
|
609
|
+
indexName = src;
|
|
610
|
+
}
|
|
462
611
|
|
|
463
|
-
|
|
612
|
+
const associationIndex = indexes.find(([idxName]) => idxName === indexName);
|
|
613
|
+
return associationIndex && associationIndex[0];
|
|
614
|
+
};
|
|
464
615
|
|
|
465
616
|
let privateModeCheckResult;
|
|
466
617
|
|
|
@@ -773,3 +924,66 @@ export class DeferredCallbackResolver {
|
|
|
773
924
|
this.limitPromise.resolve(LimitTimerRaceResolvedValues.LIMIT);
|
|
774
925
|
}
|
|
775
926
|
}
|
|
927
|
+
|
|
928
|
+
/**
|
|
929
|
+
* merge two sets of patches created by immer produce.
|
|
930
|
+
* newPatches take precedent over oldPatches for patches modifying the same path.
|
|
931
|
+
* In the case many consecutive pathces are merged the original model should
|
|
932
|
+
* always be the root model.
|
|
933
|
+
*
|
|
934
|
+
* Example:
|
|
935
|
+
* A -> B, patches1
|
|
936
|
+
* B -> C, patches2
|
|
937
|
+
*
|
|
938
|
+
* mergePatches(A, patches1, patches2) to get patches for A -> C
|
|
939
|
+
*
|
|
940
|
+
* @param originalSource the original Model the patches should be applied to
|
|
941
|
+
* @param oldPatches immer produce patch list
|
|
942
|
+
* @param newPatches immer produce patch list (will take precedence)
|
|
943
|
+
* @return merged patches
|
|
944
|
+
*/
|
|
945
|
+
export function mergePatches<T>(
|
|
946
|
+
originalSource: T,
|
|
947
|
+
oldPatches: Patch[],
|
|
948
|
+
newPatches: Patch[]
|
|
949
|
+
): Patch[] {
|
|
950
|
+
const patchesToMerge = oldPatches.concat(newPatches);
|
|
951
|
+
let patches: Patch[];
|
|
952
|
+
produce(
|
|
953
|
+
originalSource,
|
|
954
|
+
draft => {
|
|
955
|
+
applyPatches(draft, patchesToMerge);
|
|
956
|
+
},
|
|
957
|
+
p => {
|
|
958
|
+
patches = p;
|
|
959
|
+
}
|
|
960
|
+
);
|
|
961
|
+
return patches;
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
/* Backwards-compatability for schema generated prior to custom primary key support:
|
|
965
|
+
the single field `targetName` has been replaced with an array of `targetNames`
|
|
966
|
+
*/
|
|
967
|
+
export function extractTargetNamesFromSrc(src: any): string[] | undefined {
|
|
968
|
+
const targetName = src?.targetName;
|
|
969
|
+
const targetNames = src?.targetNames;
|
|
970
|
+
|
|
971
|
+
if (Array.isArray(targetNames) && targetNames?.length) {
|
|
972
|
+
return targetNames;
|
|
973
|
+
} else if (typeof targetName === 'string') {
|
|
974
|
+
return [targetName];
|
|
975
|
+
} else {
|
|
976
|
+
return undefined;
|
|
977
|
+
}
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
// Generates snake-cased index name from an aray of key field names
|
|
981
|
+
// E.g. for keys `[id, title]` => 'id-title'
|
|
982
|
+
export function indexNameFromKeys(keys: string[]): string {
|
|
983
|
+
return keys.reduce((prev: string, cur: string, idx: number) => {
|
|
984
|
+
if (idx === 0) {
|
|
985
|
+
return cur;
|
|
986
|
+
}
|
|
987
|
+
return `${prev}-${cur}`;
|
|
988
|
+
}, '');
|
|
989
|
+
}
|
package/ssr/package.json
CHANGED