-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: entity mutation validators (#67)
* entity mutation validators * pr feedback * tests
- Loading branch information
Showing
8 changed files
with
424 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
147 changes: 147 additions & 0 deletions
147
packages/entity-database-adapter-knex/src/testfixtures/PostgresValidatorTestEntity.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
import { | ||
AlwaysAllowPrivacyPolicyRule, | ||
EntityPrivacyPolicy, | ||
ViewerContext, | ||
UUIDField, | ||
StringField, | ||
EntityConfiguration, | ||
DatabaseAdapterFlavor, | ||
CacheAdapterFlavor, | ||
EntityCompanionDefinition, | ||
Entity, | ||
EntityMutationTrigger, | ||
EntityQueryContext, | ||
} from '@expo/entity'; | ||
import Knex from 'knex'; | ||
|
||
type PostgresValidatorTestEntityFields = { | ||
id: string; | ||
name: string | null; | ||
}; | ||
|
||
export default class PostgresValidatorTestEntity extends Entity< | ||
PostgresValidatorTestEntityFields, | ||
string, | ||
ViewerContext | ||
> { | ||
static getCompanionDefinition(): EntityCompanionDefinition< | ||
PostgresValidatorTestEntityFields, | ||
string, | ||
ViewerContext, | ||
PostgresValidatorTestEntity, | ||
PostgresValidatorTestEntityPrivacyPolicy | ||
> { | ||
return postgresTestEntityCompanionDefinition; | ||
} | ||
|
||
public static async createOrTruncatePostgresTable(knex: Knex): Promise<void> { | ||
await knex.raw('CREATE EXTENSION IF NOT EXISTS "uuid-ossp"'); // for uuid_generate_v4() | ||
|
||
const tableName = this.getCompanionDefinition().entityConfiguration.tableName; | ||
const hasTable = await knex.schema.hasTable(tableName); | ||
if (!hasTable) { | ||
await knex.schema.createTable(tableName, (table) => { | ||
table.uuid('id').defaultTo(knex.raw('uuid_generate_v4()')).primary(); | ||
table.string('name'); | ||
}); | ||
} | ||
await knex.into(tableName).truncate(); | ||
} | ||
|
||
public static async dropPostgresTable(knex: Knex): Promise<void> { | ||
const tableName = this.getCompanionDefinition().entityConfiguration.tableName; | ||
const hasTable = await knex.schema.hasTable(tableName); | ||
if (hasTable) { | ||
await knex.schema.dropTable(tableName); | ||
} | ||
} | ||
} | ||
|
||
class PostgresValidatorTestEntityPrivacyPolicy extends EntityPrivacyPolicy< | ||
PostgresValidatorTestEntityFields, | ||
string, | ||
ViewerContext, | ||
PostgresValidatorTestEntity | ||
> { | ||
protected readonly createRules = [ | ||
new AlwaysAllowPrivacyPolicyRule< | ||
PostgresValidatorTestEntityFields, | ||
string, | ||
ViewerContext, | ||
PostgresValidatorTestEntity | ||
>(), | ||
]; | ||
protected readonly readRules = [ | ||
new AlwaysAllowPrivacyPolicyRule< | ||
PostgresValidatorTestEntityFields, | ||
string, | ||
ViewerContext, | ||
PostgresValidatorTestEntity | ||
>(), | ||
]; | ||
protected readonly updateRules = [ | ||
new AlwaysAllowPrivacyPolicyRule< | ||
PostgresValidatorTestEntityFields, | ||
string, | ||
ViewerContext, | ||
PostgresValidatorTestEntity | ||
>(), | ||
]; | ||
protected readonly deleteRules = [ | ||
new AlwaysAllowPrivacyPolicyRule< | ||
PostgresValidatorTestEntityFields, | ||
string, | ||
ViewerContext, | ||
PostgresValidatorTestEntity | ||
>(), | ||
]; | ||
} | ||
|
||
class ThrowConditionallyTrigger extends EntityMutationTrigger< | ||
PostgresValidatorTestEntityFields, | ||
string, | ||
ViewerContext, | ||
PostgresValidatorTestEntity | ||
> { | ||
constructor( | ||
private fieldName: keyof PostgresValidatorTestEntityFields, | ||
private badValue: string | ||
) { | ||
super(); | ||
} | ||
|
||
async executeAsync( | ||
_viewerContext: ViewerContext, | ||
_queryContext: EntityQueryContext, | ||
entity: PostgresValidatorTestEntity | ||
): Promise<void> { | ||
if (entity.getField(this.fieldName) === this.badValue) { | ||
throw new Error(`${this.fieldName} cannot have value ${this.badValue}`); | ||
} | ||
} | ||
} | ||
|
||
export const postgresTestEntityConfiguration = new EntityConfiguration< | ||
PostgresValidatorTestEntityFields | ||
>({ | ||
idField: 'id', | ||
tableName: 'postgres_test_entities', | ||
schema: { | ||
id: new UUIDField({ | ||
columnName: 'id', | ||
cache: true, | ||
}), | ||
name: new StringField({ | ||
columnName: 'name', | ||
}), | ||
}, | ||
databaseAdapterFlavor: DatabaseAdapterFlavor.POSTGRES, | ||
cacheAdapterFlavor: CacheAdapterFlavor.REDIS, | ||
}); | ||
|
||
const postgresTestEntityCompanionDefinition = new EntityCompanionDefinition({ | ||
entityClass: PostgresValidatorTestEntity, | ||
entityConfiguration: postgresTestEntityConfiguration, | ||
privacyPolicyClass: PostgresValidatorTestEntityPrivacyPolicy, | ||
mutationValidators: [new ThrowConditionallyTrigger('name', 'beforeCreateAndBeforeUpdate')], | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.