### Publish New Version with Lerna Source: https://github.com/expo/entity/blob/main/README.md This command publishes a new version of the project using Lerna. It requires Git to be set up and Lerna installed. The command takes an argument for the version bump type (patch, minor, or major) and uses conventional commits for changelog generation. ```bash git checkout main yarn lerna publish [patch|minor|major] -- --conventional-commits --force-publish ``` -------------------------------- ### Entity Photo Privacy Policy Example (TypeScript) Source: https://github.com/expo/entity/blob/main/README.md Demonstrates how to define authorization rules for reading a photo entity using Entity's policy system. It includes example rules for ownership and organizational permissions. ```typescript class PhotoPrivacyPolicy { const readRules = [ new AllowIfOwnerRule(), new AllowIfOrganizationPermissionRule(), ]; } // in the view, for example async function get_photo_page(viewer: ViewerContext): string { const photo = await PhotoEntity.loader(viewer).loadById(id); return render_html(photo); } ``` -------------------------------- ### Install @expo/entity-codemod Source: https://github.com/expo/entity/blob/main/packages/entity-codemod/README.md Installs the @expo/entity-codemod package as a development dependency. ```bash yarn add -D @expo/entity-codemod ``` -------------------------------- ### Instantiate Local Memory Secondary Cache Loader (TypeScript) Source: https://github.com/expo/entity/blob/main/packages/entity-secondary-cache-local-memory/README.md Demonstrates how to create an instance of a concrete implementation of `EntitySecondaryCacheLoader` using `LocalMemorySecondaryEntityCache` and a LRU cache. This setup is for testing purposes. ```typescript const secondaryCacheLoader = new TestSecondaryLocalMemoryCacheLoader( new LocalMemorySecondaryEntityCache( GenericLocalMemoryCacher.createLRUCache({}) ), LocalMemoryTestEntity.loader(viewerContext) ); ``` -------------------------------- ### Instantiate EntityCompanionProvider with Knex Postgres Adapter Source: https://github.com/expo/entity/blob/main/packages/entity-database-adapter-knex/README.md Demonstrates how to instantiate `EntityCompanionProvider` by providing a Knex database adapter for PostgreSQL. It requires a Knex instance configured for the 'pg' client and connection details. ```typescript import { knex, Knex } from 'knex'; const knexInstance = knex({ client: 'pg', connection: { user: process.env['PGUSER'], password: process.env['PGPASSWORD'], host: process.env['PGHOST'], port: parseInt(nullthrows(process.env['PGPORT']), 10), database: process.env['PGDATABASE'], }, }); export const createDefaultEntityCompanionProvider = ( metricsAdapter: IEntityMetricsAdapter = new NoOpEntityMetricsAdapter() ): EntityCompanionProvider => { return new EntityCompanionProvider( metricsAdapter, { // add the knex database adapter flavor ['postgres']: { adapter: PostgresEntityDatabaseAdapter, queryContextProvider: new PostgresEntityQueryContextProvider(knexInstance), }, }, { ... } ); }; ``` -------------------------------- ### Authorization Logic Comparison (Python/Pseudocode) Source: https://github.com/expo/entity/blob/main/README.md Illustrates traditional authorization patterns in Python and pseudocode, contrasting them with Entity's integrated approach. It shows how authorization checks can be missed in manual implementations. ```python class PhotoModel def authorize_read(): if rules.is_photo_owner(user, photo) return true if rules.has_organization_permission(user, photo) return true def authorize_create(): ... PhotoView def render(): photo = Photo.find(params[:id]) authorize(photo, 'read') render_html(photo) ``` -------------------------------- ### Create Default EntityCompanionProvider with LocalMemoryCacheAdapterProvider Source: https://github.com/expo/entity/blob/main/packages/entity-cache-adapter-local-memory/README.md Demonstrates how to instantiate an EntityCompanionProvider with the local-memory cache adapter. This involves providing the cacheAdapterProvider during the constructor call. ```typescript export const createDefaultEntityCompanionProvider = ( metricsAdapter: IEntityMetricsAdapter = new NoOpEntityMetricsAdapter() ): EntityCompanionProvider => { return new EntityCompanionProvider( metricsAdapter, { ... }, { ['local-memory']: { cacheAdapterProvider: new LocalMemoryCacheAdapterProvider.getProvider(), }, } ); }; ``` -------------------------------- ### Implement and Use Redis Secondary Cache Loader Source: https://github.com/expo/entity/blob/main/packages/entity-secondary-cache-redis/README.md Demonstrates how to create a concrete implementation of EntitySecondaryCacheLoader using RedisSecondaryEntityCache. It shows instantiation with configuration and cache context, defining a key serialization function, and then loading entities. ```typescript const secondaryCacheLoader = new TestSecondaryRedisCacheLoader( new RedisSecondaryEntityCache( redisTestEntityConfiguration, genericRedisCacheContext, (loadParams) => `${loadParams.id}` ), RedisTestEntity.loader(viewerContext) ); const loadParams = { id: createdEntity.getID() }; const results = await secondaryCacheLoader.loadManyAsync([loadParams]); ``` -------------------------------- ### Configure Redis Cache Adapter for Expo Entity Source: https://github.com/expo/entity/blob/main/packages/entity-cache-adapter-redis/README.md Demonstrates how to instantiate and configure the Redis cache adapter within the EntityCompanionProvider. It includes setting up the ioredis client, defining a key generation function, and specifying cache expiration times. ```typescript import Redis from 'ioredis'; const genericRedisCacherContext = { redisClient: new Redis(new URL(process.env['REDIS_URL']!).toString()), makeKeyFn(...parts: string[]): string { const delimiter = ':'; const escapedParts = parts.map((part) => part.replace('\', '\\').replace(delimiter, `\${delimiter}`) ); return escapedParts.join(delimiter); }, cacheKeyPrefix: 'ent-', ttlSecondsPositive: 86400, // 1 day ttlSecondsNegative: 600, // 10 minutes }; export const createDefaultEntityCompanionProvider = ( metricsAdapter: IEntityMetricsAdapter = new NoOpEntityMetricsAdapter() ): EntityCompanionProvider => { return new EntityCompanionProvider( metricsAdapter, { ... }, { ['redis']: { cacheAdapterProvider: new RedisCacheAdapterProvider(genericRedisCacheContext), }, } ); }; ``` -------------------------------- ### Load Entities with Secondary Cache Loader (TypeScript) Source: https://github.com/expo/entity/blob/main/packages/entity-secondary-cache-local-memory/README.md Shows how to load entities using the previously created `secondaryCacheLoader`. It takes an array of load parameters and returns the loaded entities. ```typescript const loadParams = { id: createdEntity.getID() }; const results = await secondaryCacheLoader.loadManyAsync([loadParams]); ``` -------------------------------- ### Apply v0.39.0 to v0.40.0 codemod Source: https://github.com/expo/entity/blob/main/packages/entity-codemod/README.md Applies the codemod for upgrading @expo/entity from version 0.39.0 to 0.40.0 to the 'src' directory. ```sh yarn jscodeshift src -t node_modules/@expo/entity-codemod/build/v0.39.0-v0.40.0.js ``` -------------------------------- ### Configure jscodeshift in package.json Source: https://github.com/expo/entity/blob/main/packages/entity-codemod/README.md Configures the jscodeshift CLI in the package.json scripts section to use TypeScript parsing and extensions. ```json { "scripts": { "jscodeshift": "jscodeshift --extensions=ts --parser=ts" } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.