@expo/entity 0.44.0 → 0.45.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.
@@ -122,7 +122,11 @@ class AuthorizationResultBasedEntityLoader {
122
122
  return (0, maps_1.mapMap)(entityResults, (entityResultsForId, id) => {
123
123
  const entityResult = entityResultsForId[0];
124
124
  return (entityResult ??
125
- (0, results_1.result)(new EntityNotFoundError_1.default(this.entityClass, this.entityConfiguration.idField, id)));
125
+ (0, results_1.result)(new EntityNotFoundError_1.default({
126
+ entityClass: this.entityClass,
127
+ fieldName: this.entityConfiguration.idField,
128
+ fieldValue: id,
129
+ })));
126
130
  });
127
131
  }
128
132
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"AuthorizationResultBasedEntityLoader.js","sourceRoot":"","sources":["../src/AuthorizationResultBasedEntityLoader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AuthorizationResultBasedEntityLoader.js","sourceRoot":"","sources":["../src/AuthorizationResultBasedEntityLoader.ts"],"names":[],"mappings":"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"}
@@ -3,8 +3,15 @@ import { IEntityClass } from '../Entity';
3
3
  import EntityPrivacyPolicy from '../EntityPrivacyPolicy';
4
4
  import ReadonlyEntity from '../ReadonlyEntity';
5
5
  import ViewerContext from '../ViewerContext';
6
+ type EntityNotFoundOptions<TFields extends Record<string, any>, TIDField extends keyof NonNullable<Pick<TFields, TSelectedFields>>, TViewerContext extends ViewerContext, TEntity extends ReadonlyEntity<TFields, TIDField, TViewerContext, TSelectedFields>, TPrivacyPolicy extends EntityPrivacyPolicy<TFields, TIDField, TViewerContext, TEntity, TSelectedFields>, N extends keyof TFields, TSelectedFields extends keyof TFields = keyof TFields> = {
7
+ entityClass: IEntityClass<TFields, TIDField, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields>;
8
+ fieldName: N;
9
+ fieldValue: TFields[N];
10
+ };
6
11
  export default class EntityNotFoundError<TFields extends Record<string, any>, TIDField extends keyof NonNullable<Pick<TFields, TSelectedFields>>, TViewerContext extends ViewerContext, TEntity extends ReadonlyEntity<TFields, TIDField, TViewerContext, TSelectedFields>, TPrivacyPolicy extends EntityPrivacyPolicy<TFields, TIDField, TViewerContext, TEntity, TSelectedFields>, N extends keyof TFields, TSelectedFields extends keyof TFields = keyof TFields> extends EntityError {
7
12
  readonly state = EntityErrorState.PERMANENT;
8
13
  readonly code = EntityErrorCode.ERR_ENTITY_NOT_FOUND;
9
- constructor(entityClass: IEntityClass<TFields, TIDField, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields>, fieldName: N, fieldValue: TFields[N]);
14
+ constructor(message: string);
15
+ constructor(options: EntityNotFoundOptions<TFields, TIDField, TViewerContext, TEntity, TPrivacyPolicy, N, TSelectedFields>);
10
16
  }
17
+ export {};
@@ -37,8 +37,13 @@ const EntityError_1 = __importStar(require("./EntityError"));
37
37
  class EntityNotFoundError extends EntityError_1.default {
38
38
  state = EntityError_1.EntityErrorState.PERMANENT;
39
39
  code = EntityError_1.EntityErrorCode.ERR_ENTITY_NOT_FOUND;
40
- constructor(entityClass, fieldName, fieldValue) {
41
- super(`Entity not found: ${entityClass.name} (${String(fieldName)} = ${fieldValue})`);
40
+ constructor(messageOrOptions) {
41
+ if (typeof messageOrOptions === 'string') {
42
+ super(messageOrOptions);
43
+ }
44
+ else {
45
+ super(`Entity not found: ${messageOrOptions.entityClass.name} (${String(messageOrOptions.fieldName)} = ${messageOrOptions.fieldValue})`);
46
+ }
42
47
  }
43
48
  }
44
49
  exports.default = EntityNotFoundError;
@@ -1 +1 @@
1
- {"version":3,"file":"EntityNotFoundError.js","sourceRoot":"","sources":["../../src/errors/EntityNotFoundError.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6DAA+E;AAM/E,MAAqB,mBAcnB,SAAQ,qBAAW;IACH,KAAK,GAAG,8BAAgB,CAAC,SAAS,CAAC;IACnC,IAAI,GAAG,6BAAe,CAAC,oBAAoB,CAAC;IAE5D,YACE,WAOC,EACD,SAAY,EACZ,UAAsB;QAEtB,KAAK,CAAC,qBAAqB,WAAW,CAAC,IAAI,KAAK,MAAM,CAAC,SAAS,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC;IACxF,CAAC;CACF;AAhCD,sCAgCC"}
1
+ {"version":3,"file":"EntityNotFoundError.js","sourceRoot":"","sources":["../../src/errors/EntityNotFoundError.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6DAA+E;AAiC/E,MAAqB,mBAcnB,SAAQ,qBAAW;IACH,KAAK,GAAG,8BAAgB,CAAC,SAAS,CAAC;IACnC,IAAI,GAAG,6BAAe,CAAC,oBAAoB,CAAC;IAe5D,YACE,gBAUK;QAEL,IAAI,OAAO,gBAAgB,KAAK,QAAQ,EAAE,CAAC;YACzC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,KAAK,CACH,qBAAqB,gBAAgB,CAAC,WAAW,CAAC,IAAI,KAAK,MAAM,CAAC,gBAAgB,CAAC,SAAS,CAAC,MAAM,gBAAgB,CAAC,UAAU,GAAG,CAClI,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AApDD,sCAoDC"}
package/build/index.d.ts CHANGED
@@ -83,6 +83,7 @@ export { default as AlwaysDenyPrivacyPolicyRule } from './rules/AlwaysDenyPrivac
83
83
  export { default as AlwaysSkipPrivacyPolicyRule } from './rules/AlwaysSkipPrivacyPolicyRule';
84
84
  export { default as PrivacyPolicyRule } from './rules/PrivacyPolicyRule';
85
85
  export * from './rules/PrivacyPolicyRule';
86
+ export * from './utils/EntityCreationUtils';
86
87
  export * from './utils/EntityPrivacyUtils';
87
88
  export * from './utils/mergeEntityMutationTriggerConfigurations';
88
89
  export * from './utils/collections/maps';
package/build/index.js CHANGED
@@ -146,6 +146,7 @@ Object.defineProperty(exports, "AlwaysSkipPrivacyPolicyRule", { enumerable: true
146
146
  var PrivacyPolicyRule_1 = require("./rules/PrivacyPolicyRule");
147
147
  Object.defineProperty(exports, "PrivacyPolicyRule", { enumerable: true, get: function () { return __importDefault(PrivacyPolicyRule_1).default; } });
148
148
  __exportStar(require("./rules/PrivacyPolicyRule"), exports);
149
+ __exportStar(require("./utils/EntityCreationUtils"), exports);
149
150
  __exportStar(require("./utils/EntityPrivacyUtils"), exports);
150
151
  __exportStar(require("./utils/mergeEntityMutationTriggerConfigurations"), exports);
151
152
  __exportStar(require("./utils/collections/maps"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"root":["../src/authorizationresultbasedentityassociationloader.ts","../src/authorizationresultbasedentityloader.ts","../src/authorizationresultbasedentitymutator.ts","../src/composedentitycacheadapter.ts","../src/composedsecondaryentitycache.ts","../src/enforcingentityassociationloader.ts","../src/enforcingentitycreator.ts","../src/enforcingentitydeleter.ts","../src/enforcingentityloader.ts","../src/enforcingentityupdater.ts","../src/entity.ts","../src/entityassociationloader.ts","../src/entitycompanion.ts","../src/entitycompanionprovider.ts","../src/entityconfiguration.ts","../src/entitycreator.ts","../src/entitydatabaseadapter.ts","../src/entitydeleter.ts","../src/entityfielddefinition.ts","../src/entityfields.ts","../src/entityloader.ts","../src/entityloaderfactory.ts","../src/entityloaderutils.ts","../src/entitymutationinfo.ts","../src/entitymutationtriggerconfiguration.ts","../src/entitymutationvalidator.ts","../src/entitymutatorfactory.ts","../src/entityprivacypolicy.ts","../src/entityquerycontext.ts","../src/entityquerycontextprovider.ts","../src/entitysecondarycacheloader.ts","../src/entityupdater.ts","../src/genericentitycacheadapter.ts","../src/genericsecondaryentitycache.ts","../src/ientitycacheadapter.ts","../src/ientitycacheadapterprovider.ts","../src/ientitydatabaseadapterprovider.ts","../src/ientitygenericcacher.ts","../src/readonlyentity.ts","../src/viewercontext.ts","../src/viewerscopedentitycompanion.ts","../src/viewerscopedentitycompanionprovider.ts","../src/viewerscopedentityloaderfactory.ts","../src/viewerscopedentitymutatorfactory.ts","../src/entityutils.ts","../src/index.ts","../src/errors/entitycacheadaptererror.ts","../src/errors/entitydatabaseadaptererror.ts","../src/errors/entityerror.ts","../src/errors/entityinvalidfieldvalueerror.ts","../src/errors/entitynotauthorizederror.ts","../src/errors/entitynotfounderror.ts","../src/internal/compositefieldholder.ts","../src/internal/compositefieldvaluemap.ts","../src/internal/entitydatamanager.ts","../src/internal/entityfieldtransformationutils.ts","../src/internal/entityloadinterfaces.ts","../src/internal/entitytabledatacoordinator.ts","../src/internal/readthroughentitycache.ts","../src/internal/singlefieldholder.ts","../src/metrics/entitymetricsutils.ts","../src/metrics/ientitymetricsadapter.ts","../src/metrics/noopentitymetricsadapter.ts","../src/rules/alwaysallowprivacypolicyrule.ts","../src/rules/alwaysdenyprivacypolicyrule.ts","../src/rules/alwaysskipprivacypolicyrule.ts","../src/rules/privacypolicyrule.ts","../src/utils/entityprivacyutils.ts","../src/utils/mergeentitymutationtriggerconfigurations.ts","../src/utils/collections/serializablekeymap.ts","../src/utils/collections/maps.ts","../src/utils/collections/sets.ts"],"version":"5.8.3"}
1
+ {"root":["../src/authorizationresultbasedentityassociationloader.ts","../src/authorizationresultbasedentityloader.ts","../src/authorizationresultbasedentitymutator.ts","../src/composedentitycacheadapter.ts","../src/composedsecondaryentitycache.ts","../src/enforcingentityassociationloader.ts","../src/enforcingentitycreator.ts","../src/enforcingentitydeleter.ts","../src/enforcingentityloader.ts","../src/enforcingentityupdater.ts","../src/entity.ts","../src/entityassociationloader.ts","../src/entitycompanion.ts","../src/entitycompanionprovider.ts","../src/entityconfiguration.ts","../src/entitycreator.ts","../src/entitydatabaseadapter.ts","../src/entitydeleter.ts","../src/entityfielddefinition.ts","../src/entityfields.ts","../src/entityloader.ts","../src/entityloaderfactory.ts","../src/entityloaderutils.ts","../src/entitymutationinfo.ts","../src/entitymutationtriggerconfiguration.ts","../src/entitymutationvalidator.ts","../src/entitymutatorfactory.ts","../src/entityprivacypolicy.ts","../src/entityquerycontext.ts","../src/entityquerycontextprovider.ts","../src/entitysecondarycacheloader.ts","../src/entityupdater.ts","../src/genericentitycacheadapter.ts","../src/genericsecondaryentitycache.ts","../src/ientitycacheadapter.ts","../src/ientitycacheadapterprovider.ts","../src/ientitydatabaseadapterprovider.ts","../src/ientitygenericcacher.ts","../src/readonlyentity.ts","../src/viewercontext.ts","../src/viewerscopedentitycompanion.ts","../src/viewerscopedentitycompanionprovider.ts","../src/viewerscopedentityloaderfactory.ts","../src/viewerscopedentitymutatorfactory.ts","../src/entityutils.ts","../src/index.ts","../src/errors/entitycacheadaptererror.ts","../src/errors/entitydatabaseadaptererror.ts","../src/errors/entityerror.ts","../src/errors/entityinvalidfieldvalueerror.ts","../src/errors/entitynotauthorizederror.ts","../src/errors/entitynotfounderror.ts","../src/internal/compositefieldholder.ts","../src/internal/compositefieldvaluemap.ts","../src/internal/entitydatamanager.ts","../src/internal/entityfieldtransformationutils.ts","../src/internal/entityloadinterfaces.ts","../src/internal/entitytabledatacoordinator.ts","../src/internal/readthroughentitycache.ts","../src/internal/singlefieldholder.ts","../src/metrics/entitymetricsutils.ts","../src/metrics/ientitymetricsadapter.ts","../src/metrics/noopentitymetricsadapter.ts","../src/rules/alwaysallowprivacypolicyrule.ts","../src/rules/alwaysdenyprivacypolicyrule.ts","../src/rules/alwaysskipprivacypolicyrule.ts","../src/rules/privacypolicyrule.ts","../src/utils/entitycreationutils.ts","../src/utils/entityprivacyutils.ts","../src/utils/mergeentitymutationtriggerconfigurations.ts","../src/utils/collections/serializablekeymap.ts","../src/utils/collections/maps.ts","../src/utils/collections/sets.ts"],"version":"5.8.3"}
@@ -0,0 +1,14 @@
1
+ import { IEntityClass } from '../Entity';
2
+ import EntityPrivacyPolicy from '../EntityPrivacyPolicy';
3
+ import { EntityTransactionalQueryContext } from '../EntityQueryContext';
4
+ import ReadonlyEntity from '../ReadonlyEntity';
5
+ import ViewerContext from '../ViewerContext';
6
+ /**
7
+ * Create an entity if it doesn't exist, or get the existing entity if it does.
8
+ */
9
+ export declare function createOrGetExistingAsync<TFields extends object, TIDField extends keyof NonNullable<Pick<TFields, TSelectedFields>>, TViewerContext extends ViewerContext, TEntity extends ReadonlyEntity<TFields, TIDField, TViewerContext, TSelectedFields>, TPrivacyPolicy extends EntityPrivacyPolicy<TFields, TIDField, TViewerContext, TEntity, TSelectedFields>, TGetArgs, TCreateArgs, TSelectedFields extends keyof TFields = keyof TFields>(viewerContext: TViewerContext, entityClass: IEntityClass<TFields, TIDField, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields>, getAsync: (viewerContext: TViewerContext, getArgs: TGetArgs, queryContext?: EntityTransactionalQueryContext) => Promise<TEntity | null>, getArgs: TGetArgs, createAsync: (viewerContext: TViewerContext, createArgs: TCreateArgs, queryContext?: EntityTransactionalQueryContext) => Promise<TEntity>, createArgs: TCreateArgs, queryContext?: EntityTransactionalQueryContext): Promise<TEntity>;
10
+ /**
11
+ * Account for concurrent requests that may try to create the same entity.
12
+ * Return the existing entity if we get a Unique Constraint error.
13
+ */
14
+ export declare function createWithUniqueConstraintRecoveryAsync<TFields extends object, TIDField extends keyof NonNullable<Pick<TFields, TSelectedFields>>, TViewerContext extends ViewerContext, TEntity extends ReadonlyEntity<TFields, TIDField, TViewerContext, TSelectedFields>, TPrivacyPolicy extends EntityPrivacyPolicy<TFields, TIDField, TViewerContext, TEntity, TSelectedFields>, TGetArgs, TCreateArgs, TSelectedFields extends keyof TFields = keyof TFields>(viewerContext: TViewerContext, entityClass: IEntityClass<TFields, TIDField, TViewerContext, TEntity, TPrivacyPolicy, TSelectedFields>, getAsync: (viewerContext: TViewerContext, getArgs: TGetArgs, queryContext?: EntityTransactionalQueryContext) => Promise<TEntity | null>, getArgs: TGetArgs, createAsync: (viewerContext: TViewerContext, createArgs: TCreateArgs, queryContext?: EntityTransactionalQueryContext) => Promise<TEntity>, createArgs: TCreateArgs, queryContext?: EntityTransactionalQueryContext): Promise<TEntity>;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createOrGetExistingAsync = createOrGetExistingAsync;
7
+ exports.createWithUniqueConstraintRecoveryAsync = createWithUniqueConstraintRecoveryAsync;
8
+ const EntityDatabaseAdapterError_1 = require("../errors/EntityDatabaseAdapterError");
9
+ const EntityNotFoundError_1 = __importDefault(require("../errors/EntityNotFoundError"));
10
+ /**
11
+ * Create an entity if it doesn't exist, or get the existing entity if it does.
12
+ */
13
+ async function createOrGetExistingAsync(viewerContext, entityClass, getAsync, getArgs, createAsync, createArgs, queryContext) {
14
+ if (!queryContext) {
15
+ const maybeEntity = await getAsync(viewerContext, getArgs);
16
+ if (maybeEntity) {
17
+ return maybeEntity;
18
+ }
19
+ }
20
+ else {
21
+ // This is done in a nested transaction since entity may negatively cache load results per-transaction (when configured).
22
+ // Without it, it would
23
+ // 1. load the entity in the current query context, negatively cache it
24
+ // 2. then try to create it in the nested transaction, which may fail due to a unique constraint error
25
+ // 3. then try to load the entity again in the current query context, which would return null due to negative cache
26
+ const maybeEntity = await queryContext.runInNestedTransactionAsync((nestedQueryContext) => getAsync(viewerContext, getArgs, nestedQueryContext));
27
+ if (maybeEntity) {
28
+ return maybeEntity;
29
+ }
30
+ }
31
+ return await createWithUniqueConstraintRecoveryAsync(viewerContext, entityClass, getAsync, getArgs, createAsync, createArgs, queryContext);
32
+ }
33
+ /**
34
+ * Account for concurrent requests that may try to create the same entity.
35
+ * Return the existing entity if we get a Unique Constraint error.
36
+ */
37
+ async function createWithUniqueConstraintRecoveryAsync(viewerContext, entityClass, getAsync, getArgs, createAsync, createArgs, queryContext) {
38
+ try {
39
+ if (!queryContext) {
40
+ return await createAsync(viewerContext, createArgs);
41
+ }
42
+ return await queryContext.runInNestedTransactionAsync((nestedQueryContext) => createAsync(viewerContext, createArgs, nestedQueryContext));
43
+ }
44
+ catch (e) {
45
+ if (e instanceof EntityDatabaseAdapterError_1.EntityDatabaseAdapterUniqueConstraintError) {
46
+ const entity = await getAsync(viewerContext, getArgs, queryContext);
47
+ if (!entity) {
48
+ throw new EntityNotFoundError_1.default(`Expected entity to exist after unique constraint error: ${entityClass.name}`);
49
+ }
50
+ return entity;
51
+ }
52
+ else {
53
+ throw e;
54
+ }
55
+ }
56
+ }
57
+ //# sourceMappingURL=EntityCreationUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityCreationUtils.js","sourceRoot":"","sources":["../../src/utils/EntityCreationUtils.ts"],"names":[],"mappings":";;;;;AAWA,4DAkEC;AAMD,0FA2DC;AAzID,qFAAkG;AAClG,wFAAgE;AAEhE;;GAEG;AACI,KAAK,UAAU,wBAAwB,CAgB5C,aAA6B,EAC7B,WAOC,EACD,QAI4B,EAC5B,OAAiB,EACjB,WAIqB,EACrB,UAAuB,EACvB,YAA8C;IAE9C,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAC3D,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,WAAW,CAAC;QACrB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,yHAAyH;QACzH,uBAAuB;QACvB,uEAAuE;QACvE,sGAAsG;QACtG,mHAAmH;QACnH,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,2BAA2B,CAAC,CAAC,kBAAkB,EAAE,EAAE,CACxF,QAAQ,CAAC,aAAa,EAAE,OAAO,EAAE,kBAAkB,CAAC,CACrD,CAAC;QACF,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,WAAW,CAAC;QACrB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,uCAAuC,CAClD,aAAa,EACb,WAAW,EACX,QAAQ,EACR,OAAO,EACP,WAAW,EACX,UAAU,EACV,YAAY,CACb,CAAC;AACJ,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,uCAAuC,CAgB3D,aAA6B,EAC7B,WAOC,EACD,QAI4B,EAC5B,OAAiB,EACjB,WAIqB,EACrB,UAAuB,EACvB,YAA8C;IAE9C,IAAI,CAAC;QACH,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO,MAAM,WAAW,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,MAAM,YAAY,CAAC,2BAA2B,CAAC,CAAC,kBAAkB,EAAE,EAAE,CAC3E,WAAW,CAAC,aAAa,EAAE,UAAU,EAAE,kBAAkB,CAAC,CAC3D,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,uEAA0C,EAAE,CAAC;YAC5D,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;YACpE,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,IAAI,6BAAmB,CAC3B,2DAA2D,WAAW,CAAC,IAAI,EAAE,CAC9E,CAAC;YACJ,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,CAAC;QACV,CAAC;IACH,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/entity",
3
- "version": "0.44.0",
3
+ "version": "0.45.0",
4
4
  "description": "A privacy-first data model",
5
5
  "files": [
6
6
  "build",
@@ -53,5 +53,5 @@
53
53
  "uuid": "^8.3.0",
54
54
  "uuidv7": "^1.0.0"
55
55
  },
56
- "gitHead": "b9b09933e5a5b02037aa4688c5969705a29995c0"
56
+ "gitHead": "fe2d246f87adc98a13cc7c1ae57f3628769560c9"
57
57
  }
@@ -237,7 +237,13 @@ export default class AuthorizationResultBasedEntityLoader<
237
237
  const entityResult = entityResultsForId[0];
238
238
  return (
239
239
  entityResult ??
240
- result(new EntityNotFoundError(this.entityClass, this.entityConfiguration.idField, id))
240
+ result(
241
+ new EntityNotFoundError({
242
+ entityClass: this.entityClass,
243
+ fieldName: this.entityConfiguration.idField,
244
+ fieldValue: id,
245
+ }),
246
+ )
241
247
  );
242
248
  });
243
249
  }
@@ -4,6 +4,33 @@ import EntityPrivacyPolicy from '../EntityPrivacyPolicy';
4
4
  import ReadonlyEntity from '../ReadonlyEntity';
5
5
  import ViewerContext from '../ViewerContext';
6
6
 
7
+ type EntityNotFoundOptions<
8
+ TFields extends Record<string, any>,
9
+ TIDField extends keyof NonNullable<Pick<TFields, TSelectedFields>>,
10
+ TViewerContext extends ViewerContext,
11
+ TEntity extends ReadonlyEntity<TFields, TIDField, TViewerContext, TSelectedFields>,
12
+ TPrivacyPolicy extends EntityPrivacyPolicy<
13
+ TFields,
14
+ TIDField,
15
+ TViewerContext,
16
+ TEntity,
17
+ TSelectedFields
18
+ >,
19
+ N extends keyof TFields,
20
+ TSelectedFields extends keyof TFields = keyof TFields,
21
+ > = {
22
+ entityClass: IEntityClass<
23
+ TFields,
24
+ TIDField,
25
+ TViewerContext,
26
+ TEntity,
27
+ TPrivacyPolicy,
28
+ TSelectedFields
29
+ >;
30
+ fieldName: N;
31
+ fieldValue: TFields[N];
32
+ };
33
+
7
34
  export default class EntityNotFoundError<
8
35
  TFields extends Record<string, any>,
9
36
  TIDField extends keyof NonNullable<Pick<TFields, TSelectedFields>>,
@@ -22,18 +49,38 @@ export default class EntityNotFoundError<
22
49
  public readonly state = EntityErrorState.PERMANENT;
23
50
  public readonly code = EntityErrorCode.ERR_ENTITY_NOT_FOUND;
24
51
 
52
+ constructor(message: string);
25
53
  constructor(
26
- entityClass: IEntityClass<
54
+ options: EntityNotFoundOptions<
27
55
  TFields,
28
56
  TIDField,
29
57
  TViewerContext,
30
58
  TEntity,
31
59
  TPrivacyPolicy,
60
+ N,
32
61
  TSelectedFields
33
62
  >,
34
- fieldName: N,
35
- fieldValue: TFields[N],
63
+ );
64
+
65
+ constructor(
66
+ messageOrOptions:
67
+ | string
68
+ | EntityNotFoundOptions<
69
+ TFields,
70
+ TIDField,
71
+ TViewerContext,
72
+ TEntity,
73
+ TPrivacyPolicy,
74
+ N,
75
+ TSelectedFields
76
+ >,
36
77
  ) {
37
- super(`Entity not found: ${entityClass.name} (${String(fieldName)} = ${fieldValue})`);
78
+ if (typeof messageOrOptions === 'string') {
79
+ super(messageOrOptions);
80
+ } else {
81
+ super(
82
+ `Entity not found: ${messageOrOptions.entityClass.name} (${String(messageOrOptions.fieldName)} = ${messageOrOptions.fieldValue})`,
83
+ );
84
+ }
38
85
  }
39
86
  }
@@ -0,0 +1,26 @@
1
+ import EntityDatabaseAdapterError, {
2
+ EntityDatabaseAdapterTransientError,
3
+ EntityDatabaseAdapterUnknownError,
4
+ EntityDatabaseAdapterCheckConstraintError,
5
+ EntityDatabaseAdapterExclusionConstraintError,
6
+ EntityDatabaseAdapterForeignKeyConstraintError,
7
+ EntityDatabaseAdapterNotNullConstraintError,
8
+ EntityDatabaseAdapterUniqueConstraintError,
9
+ } from '../EntityDatabaseAdapterError';
10
+
11
+ describe(EntityDatabaseAdapterError, () => {
12
+ // necessary for coverage within the entity package since these errors are
13
+ // currently only ever instantiated by database adapter implementations
14
+ it('instantiates all errors successfully', () => {
15
+ const errors = [
16
+ new EntityDatabaseAdapterTransientError('test'),
17
+ new EntityDatabaseAdapterUnknownError('test'),
18
+ new EntityDatabaseAdapterCheckConstraintError('test'),
19
+ new EntityDatabaseAdapterExclusionConstraintError('test'),
20
+ new EntityDatabaseAdapterForeignKeyConstraintError('test'),
21
+ new EntityDatabaseAdapterNotNullConstraintError('test'),
22
+ new EntityDatabaseAdapterUniqueConstraintError('test'),
23
+ ];
24
+ expect(errors).not.toBeFalsy();
25
+ });
26
+ });
package/src/index.ts CHANGED
@@ -85,6 +85,7 @@ export { default as AlwaysDenyPrivacyPolicyRule } from './rules/AlwaysDenyPrivac
85
85
  export { default as AlwaysSkipPrivacyPolicyRule } from './rules/AlwaysSkipPrivacyPolicyRule';
86
86
  export { default as PrivacyPolicyRule } from './rules/PrivacyPolicyRule';
87
87
  export * from './rules/PrivacyPolicyRule';
88
+ export * from './utils/EntityCreationUtils';
88
89
  export * from './utils/EntityPrivacyUtils';
89
90
  export * from './utils/mergeEntityMutationTriggerConfigurations';
90
91
  export * from './utils/collections/maps';
@@ -0,0 +1,143 @@
1
+ import { IEntityClass } from '../Entity';
2
+ import EntityPrivacyPolicy from '../EntityPrivacyPolicy';
3
+ import { EntityTransactionalQueryContext } from '../EntityQueryContext';
4
+ import ReadonlyEntity from '../ReadonlyEntity';
5
+ import ViewerContext from '../ViewerContext';
6
+ import { EntityDatabaseAdapterUniqueConstraintError } from '../errors/EntityDatabaseAdapterError';
7
+ import EntityNotFoundError from '../errors/EntityNotFoundError';
8
+
9
+ /**
10
+ * Create an entity if it doesn't exist, or get the existing entity if it does.
11
+ */
12
+ export async function createOrGetExistingAsync<
13
+ TFields extends object,
14
+ TIDField extends keyof NonNullable<Pick<TFields, TSelectedFields>>,
15
+ TViewerContext extends ViewerContext,
16
+ TEntity extends ReadonlyEntity<TFields, TIDField, TViewerContext, TSelectedFields>,
17
+ TPrivacyPolicy extends EntityPrivacyPolicy<
18
+ TFields,
19
+ TIDField,
20
+ TViewerContext,
21
+ TEntity,
22
+ TSelectedFields
23
+ >,
24
+ TGetArgs,
25
+ TCreateArgs,
26
+ TSelectedFields extends keyof TFields = keyof TFields,
27
+ >(
28
+ viewerContext: TViewerContext,
29
+ entityClass: IEntityClass<
30
+ TFields,
31
+ TIDField,
32
+ TViewerContext,
33
+ TEntity,
34
+ TPrivacyPolicy,
35
+ TSelectedFields
36
+ >,
37
+ getAsync: (
38
+ viewerContext: TViewerContext,
39
+ getArgs: TGetArgs,
40
+ queryContext?: EntityTransactionalQueryContext,
41
+ ) => Promise<TEntity | null>,
42
+ getArgs: TGetArgs,
43
+ createAsync: (
44
+ viewerContext: TViewerContext,
45
+ createArgs: TCreateArgs,
46
+ queryContext?: EntityTransactionalQueryContext,
47
+ ) => Promise<TEntity>,
48
+ createArgs: TCreateArgs,
49
+ queryContext?: EntityTransactionalQueryContext,
50
+ ): Promise<TEntity> {
51
+ if (!queryContext) {
52
+ const maybeEntity = await getAsync(viewerContext, getArgs);
53
+ if (maybeEntity) {
54
+ return maybeEntity;
55
+ }
56
+ } else {
57
+ // This is done in a nested transaction since entity may negatively cache load results per-transaction (when configured).
58
+ // Without it, it would
59
+ // 1. load the entity in the current query context, negatively cache it
60
+ // 2. then try to create it in the nested transaction, which may fail due to a unique constraint error
61
+ // 3. then try to load the entity again in the current query context, which would return null due to negative cache
62
+ const maybeEntity = await queryContext.runInNestedTransactionAsync((nestedQueryContext) =>
63
+ getAsync(viewerContext, getArgs, nestedQueryContext),
64
+ );
65
+ if (maybeEntity) {
66
+ return maybeEntity;
67
+ }
68
+ }
69
+ return await createWithUniqueConstraintRecoveryAsync(
70
+ viewerContext,
71
+ entityClass,
72
+ getAsync,
73
+ getArgs,
74
+ createAsync,
75
+ createArgs,
76
+ queryContext,
77
+ );
78
+ }
79
+
80
+ /**
81
+ * Account for concurrent requests that may try to create the same entity.
82
+ * Return the existing entity if we get a Unique Constraint error.
83
+ */
84
+ export async function createWithUniqueConstraintRecoveryAsync<
85
+ TFields extends object,
86
+ TIDField extends keyof NonNullable<Pick<TFields, TSelectedFields>>,
87
+ TViewerContext extends ViewerContext,
88
+ TEntity extends ReadonlyEntity<TFields, TIDField, TViewerContext, TSelectedFields>,
89
+ TPrivacyPolicy extends EntityPrivacyPolicy<
90
+ TFields,
91
+ TIDField,
92
+ TViewerContext,
93
+ TEntity,
94
+ TSelectedFields
95
+ >,
96
+ TGetArgs,
97
+ TCreateArgs,
98
+ TSelectedFields extends keyof TFields = keyof TFields,
99
+ >(
100
+ viewerContext: TViewerContext,
101
+ entityClass: IEntityClass<
102
+ TFields,
103
+ TIDField,
104
+ TViewerContext,
105
+ TEntity,
106
+ TPrivacyPolicy,
107
+ TSelectedFields
108
+ >,
109
+ getAsync: (
110
+ viewerContext: TViewerContext,
111
+ getArgs: TGetArgs,
112
+ queryContext?: EntityTransactionalQueryContext,
113
+ ) => Promise<TEntity | null>,
114
+ getArgs: TGetArgs,
115
+ createAsync: (
116
+ viewerContext: TViewerContext,
117
+ createArgs: TCreateArgs,
118
+ queryContext?: EntityTransactionalQueryContext,
119
+ ) => Promise<TEntity>,
120
+ createArgs: TCreateArgs,
121
+ queryContext?: EntityTransactionalQueryContext,
122
+ ): Promise<TEntity> {
123
+ try {
124
+ if (!queryContext) {
125
+ return await createAsync(viewerContext, createArgs);
126
+ }
127
+ return await queryContext.runInNestedTransactionAsync((nestedQueryContext) =>
128
+ createAsync(viewerContext, createArgs, nestedQueryContext),
129
+ );
130
+ } catch (e) {
131
+ if (e instanceof EntityDatabaseAdapterUniqueConstraintError) {
132
+ const entity = await getAsync(viewerContext, getArgs, queryContext);
133
+ if (!entity) {
134
+ throw new EntityNotFoundError(
135
+ `Expected entity to exist after unique constraint error: ${entityClass.name}`,
136
+ );
137
+ }
138
+ return entity;
139
+ } else {
140
+ throw e;
141
+ }
142
+ }
143
+ }
@@ -0,0 +1,354 @@
1
+ import { EntityTransactionalQueryContext } from '../../EntityQueryContext';
2
+ import ViewerContext from '../../ViewerContext';
3
+ import { EntityDatabaseAdapterUniqueConstraintError } from '../../errors/EntityDatabaseAdapterError';
4
+ import EntityNotFoundError from '../../errors/EntityNotFoundError';
5
+ import {
6
+ createOrGetExistingAsync,
7
+ createWithUniqueConstraintRecoveryAsync,
8
+ } from '../EntityCreationUtils';
9
+ import SimpleTestEntity from '../__testfixtures__/SimpleTestEntity';
10
+ import { createUnitTestEntityCompanionProvider } from '../__testfixtures__/createUnitTestEntityCompanionProvider';
11
+
12
+ type TArgs = object;
13
+
14
+ describe.each([true, false])('in transaction %p', (inTransaction) => {
15
+ describe(createOrGetExistingAsync, () => {
16
+ it('does not create when already exists', async () => {
17
+ const companionProvider = createUnitTestEntityCompanionProvider();
18
+ const viewerContext = new ViewerContext(companionProvider);
19
+
20
+ const entity = await SimpleTestEntity.creator(viewerContext).createAsync();
21
+
22
+ const args: TArgs = {};
23
+
24
+ const getFn = jest.fn(
25
+ async (
26
+ _vc: ViewerContext,
27
+ _args: TArgs,
28
+ _queryContext?: EntityTransactionalQueryContext,
29
+ ) => {
30
+ return entity;
31
+ },
32
+ );
33
+
34
+ const createFn = jest.fn(
35
+ async (vc: ViewerContext, _args: TArgs, queryContext?: EntityTransactionalQueryContext) => {
36
+ return await SimpleTestEntity.creator(vc, queryContext).createAsync();
37
+ },
38
+ );
39
+
40
+ if (inTransaction) {
41
+ await viewerContext.runInTransactionForDatabaseAdaptorFlavorAsync(
42
+ 'postgres',
43
+ async (queryContext) => {
44
+ await createOrGetExistingAsync(
45
+ viewerContext,
46
+ SimpleTestEntity,
47
+ getFn,
48
+ args,
49
+ createFn,
50
+ args,
51
+ queryContext,
52
+ );
53
+ },
54
+ );
55
+ } else {
56
+ await createOrGetExistingAsync(
57
+ viewerContext,
58
+ SimpleTestEntity,
59
+ getFn,
60
+ args,
61
+ createFn,
62
+ args,
63
+ );
64
+ }
65
+
66
+ expect(getFn).toHaveBeenCalledTimes(1);
67
+ expect(createFn).toHaveBeenCalledTimes(0);
68
+ });
69
+
70
+ it('creates when not found', async () => {
71
+ const companionProvider = createUnitTestEntityCompanionProvider();
72
+ const viewerContext = new ViewerContext(companionProvider);
73
+
74
+ const args: TArgs = {};
75
+
76
+ const getFn = jest.fn(
77
+ async (
78
+ _vc: ViewerContext,
79
+ _args: TArgs,
80
+ _queryContext?: EntityTransactionalQueryContext,
81
+ ) => {
82
+ return null;
83
+ },
84
+ );
85
+
86
+ const createFn = jest.fn(
87
+ async (vc: ViewerContext, _args: TArgs, queryContext?: EntityTransactionalQueryContext) => {
88
+ return await SimpleTestEntity.creator(vc, queryContext).createAsync();
89
+ },
90
+ );
91
+
92
+ if (inTransaction) {
93
+ await viewerContext.runInTransactionForDatabaseAdaptorFlavorAsync(
94
+ 'postgres',
95
+ async (queryContext) => {
96
+ await createOrGetExistingAsync(
97
+ viewerContext,
98
+ SimpleTestEntity,
99
+ getFn,
100
+ args,
101
+ createFn,
102
+ args,
103
+ queryContext,
104
+ );
105
+ },
106
+ );
107
+ } else {
108
+ await createOrGetExistingAsync(
109
+ viewerContext,
110
+ SimpleTestEntity,
111
+ getFn,
112
+ args,
113
+ createFn,
114
+ args,
115
+ );
116
+ }
117
+
118
+ expect(getFn).toHaveBeenCalledTimes(1);
119
+ expect(createFn).toHaveBeenCalledTimes(1);
120
+ });
121
+ });
122
+
123
+ describe(createWithUniqueConstraintRecoveryAsync, () => {
124
+ it('does not call get when creation succeeds', async () => {
125
+ const companionProvider = createUnitTestEntityCompanionProvider();
126
+ const viewerContext = new ViewerContext(companionProvider);
127
+
128
+ const args: TArgs = {};
129
+
130
+ const getFn = jest.fn(
131
+ async (
132
+ _vc: ViewerContext,
133
+ _args: TArgs,
134
+ _queryContext?: EntityTransactionalQueryContext,
135
+ ) => {
136
+ return null;
137
+ },
138
+ );
139
+
140
+ const createFn = jest.fn(
141
+ async (vc: ViewerContext, _args: TArgs, queryContext?: EntityTransactionalQueryContext) => {
142
+ return await SimpleTestEntity.creator(vc, queryContext).createAsync();
143
+ },
144
+ );
145
+
146
+ if (inTransaction) {
147
+ await viewerContext.runInTransactionForDatabaseAdaptorFlavorAsync(
148
+ 'postgres',
149
+ async (queryContext) => {
150
+ await createWithUniqueConstraintRecoveryAsync(
151
+ viewerContext,
152
+ SimpleTestEntity,
153
+ getFn,
154
+ args,
155
+ createFn,
156
+ args,
157
+ queryContext,
158
+ );
159
+ },
160
+ );
161
+ } else {
162
+ await createWithUniqueConstraintRecoveryAsync(
163
+ viewerContext,
164
+ SimpleTestEntity,
165
+ getFn,
166
+ args,
167
+ createFn,
168
+ args,
169
+ );
170
+ }
171
+
172
+ expect(getFn).toHaveBeenCalledTimes(0);
173
+ expect(createFn).toHaveBeenCalledTimes(1);
174
+ });
175
+
176
+ it('calls get when database adapter throws EntityDatabaseAdapterUniqueConstraintError', async () => {
177
+ const companionProvider = createUnitTestEntityCompanionProvider();
178
+ const viewerContext = new ViewerContext(companionProvider);
179
+
180
+ const entity = await SimpleTestEntity.creator(viewerContext).createAsync();
181
+
182
+ const args: TArgs = {};
183
+
184
+ const getFn = jest.fn(
185
+ async (
186
+ _vc: ViewerContext,
187
+ _args: TArgs,
188
+ _queryContext?: EntityTransactionalQueryContext,
189
+ ) => {
190
+ return entity;
191
+ },
192
+ );
193
+
194
+ const createFn = jest.fn(
195
+ async (
196
+ _vc: ViewerContext,
197
+ _args: TArgs,
198
+ _queryContext?: EntityTransactionalQueryContext,
199
+ ) => {
200
+ throw new EntityDatabaseAdapterUniqueConstraintError('wat');
201
+ },
202
+ );
203
+
204
+ if (inTransaction) {
205
+ await viewerContext.runInTransactionForDatabaseAdaptorFlavorAsync(
206
+ 'postgres',
207
+ async (queryContext) => {
208
+ await createWithUniqueConstraintRecoveryAsync(
209
+ viewerContext,
210
+ SimpleTestEntity,
211
+ getFn,
212
+ args,
213
+ createFn,
214
+ args,
215
+ queryContext,
216
+ );
217
+ },
218
+ );
219
+ } else {
220
+ await createWithUniqueConstraintRecoveryAsync(
221
+ viewerContext,
222
+ SimpleTestEntity,
223
+ getFn,
224
+ args,
225
+ createFn,
226
+ args,
227
+ );
228
+ }
229
+
230
+ expect(getFn).toHaveBeenCalledTimes(1);
231
+ expect(createFn).toHaveBeenCalledTimes(1);
232
+ });
233
+
234
+ it('throws an EntityNotFoundError when database adapter throws EntityDatabaseAdapterUniqueConstraintError and getFn returns null', async () => {
235
+ const companionProvider = createUnitTestEntityCompanionProvider();
236
+ const viewerContext = new ViewerContext(companionProvider);
237
+
238
+ const args: TArgs = {};
239
+
240
+ const getFn = jest.fn(
241
+ async (
242
+ _vc: ViewerContext,
243
+ _args: TArgs,
244
+ _queryContext?: EntityTransactionalQueryContext,
245
+ ) => {
246
+ return null;
247
+ },
248
+ );
249
+
250
+ const createFn = jest.fn(
251
+ async (
252
+ _vc: ViewerContext,
253
+ _args: TArgs,
254
+ _queryContext?: EntityTransactionalQueryContext,
255
+ ) => {
256
+ throw new EntityDatabaseAdapterUniqueConstraintError('wat');
257
+ },
258
+ );
259
+
260
+ if (inTransaction) {
261
+ await expect(
262
+ viewerContext.runInTransactionForDatabaseAdaptorFlavorAsync(
263
+ 'postgres',
264
+ async (queryContext) => {
265
+ return await createWithUniqueConstraintRecoveryAsync(
266
+ viewerContext,
267
+ SimpleTestEntity,
268
+ getFn,
269
+ args,
270
+ createFn,
271
+ args,
272
+ queryContext,
273
+ );
274
+ },
275
+ ),
276
+ ).rejects.toThrow(EntityNotFoundError);
277
+ } else {
278
+ await expect(
279
+ createWithUniqueConstraintRecoveryAsync(
280
+ viewerContext,
281
+ SimpleTestEntity,
282
+ getFn,
283
+ args,
284
+ createFn,
285
+ args,
286
+ ),
287
+ ).rejects.toThrow(EntityNotFoundError);
288
+ }
289
+
290
+ expect(getFn).toHaveBeenCalledTimes(1);
291
+ expect(createFn).toHaveBeenCalledTimes(1);
292
+ });
293
+
294
+ it('rethrows whatever error is thrown from database adapter if not EntityDatabaseAdapterUniqueConstraintError', async () => {
295
+ const companionProvider = createUnitTestEntityCompanionProvider();
296
+ const viewerContext = new ViewerContext(companionProvider);
297
+
298
+ const args: TArgs = {};
299
+
300
+ const getFn = jest.fn(
301
+ async (
302
+ _vc: ViewerContext,
303
+ _args: TArgs,
304
+ _queryContext?: EntityTransactionalQueryContext,
305
+ ) => {
306
+ return null;
307
+ },
308
+ );
309
+
310
+ const createFn = jest.fn(
311
+ async (
312
+ _vc: ViewerContext,
313
+ _args: TArgs,
314
+ _queryContext?: EntityTransactionalQueryContext,
315
+ ) => {
316
+ throw new Error('wat');
317
+ },
318
+ );
319
+
320
+ if (inTransaction) {
321
+ await expect(
322
+ viewerContext.runInTransactionForDatabaseAdaptorFlavorAsync(
323
+ 'postgres',
324
+ async (queryContext) => {
325
+ return await createWithUniqueConstraintRecoveryAsync(
326
+ viewerContext,
327
+ SimpleTestEntity,
328
+ getFn,
329
+ args,
330
+ createFn,
331
+ args,
332
+ queryContext,
333
+ );
334
+ },
335
+ ),
336
+ ).rejects.toThrow('wat');
337
+ } else {
338
+ await expect(
339
+ createWithUniqueConstraintRecoveryAsync(
340
+ viewerContext,
341
+ SimpleTestEntity,
342
+ getFn,
343
+ args,
344
+ createFn,
345
+ args,
346
+ ),
347
+ ).rejects.toThrow('wat');
348
+ }
349
+
350
+ expect(getFn).toHaveBeenCalledTimes(0);
351
+ expect(createFn).toHaveBeenCalledTimes(1);
352
+ });
353
+ });
354
+ });