@vicodes/strapi-orm v0.2.0
Motivation
Strapi is a great headless CMS, and a good entry point for start-ups. Sometimes it might become a core part of the project, but it can't substitute a strong backend application. This is where StrapiORM comes in. It allows the backend applications to treat Strapi as a database, and abstracts the filtering, population and sorting of the entities.
Install
npm i @vicodes/strapi-orm
Example
First create a Manager instance
const manager = new Manager({
baseUrl: 'http://localhost:1337/api',
accessToken: 'super-secret-token',
flatten: true,
})
Then create the entities that represent Strapi Content Types.
Use the StrapiEntity
decorator to specify the URI path of the Strapi Content Type, either as a string or as a
StrapiEntityOptions
object with the following properties:
interface StrapiEntityOptions {
path: string
}
import { StrapiEntity } from './strapi-entity.decorator'
@StrapiEntity('scopes')
export class Scope {
id: number
name: string
}
@StrapiEntity({ path: 'roles' })
export class Role {
id: number
name: string
scope: Scope
}
@StrapiEntity('users')
export class User {
id: number
firstName: string
lastName: string
role: Role
}
Using Repository
import { Manager } from '@vicodes/strapi-orm'
import { User } from './user.entity'
import { StrapiRepository } from './strapi.repository'
// It's important to type the repository with the entity type to get maximum of type safety
const roleRepository: StrapiRepository<Role> = manager.getRepository(Role)
const scopeRepository: StrapiRepository<Scope> = manager.getRepository(Scope)
const scope = await scopeRepository.findById(1)
const adminRole: Role = {
name: 'admin',
scope: scope,
}
await roleRepository.create(adminRole)
Using QueryBuilder
You can use the QueryBuilder to create complex queries. This will create the query params to select, populate filter and sort without the hustle of creating the query string or object.
import { Manager } from '@vicodes/strapi-orm'
import { User } from './user.entity'
import { StrapiRepository } from './strapi.repository'
const manager = new Manager({
baseUrl: 'http://localhost:1337/api',
accessToken: 'super-secret-token',
flatten: true,
})
const respository: StrapiRepository<User> = manager.getRepository(User)
const users = await respository
.createQueryBuilder()
.select(['firstName', 'lastName'])
.populate('role')
.populate('role.scope', '*', { name: { $in: ['read-only', 'read-write'] } })
.where('role.scope.name', 'read-only')
.getMany()
Overriding the default request service
StrapiORM uses a default request service that uses fetch
to make the requests to the Strapi API.
It can be overridden by passing a custom request service to the Manager constructor.
import { Manager, RequestService } from '@vicodes/strapi-orm'
class CustomRequestService extends RequestService {
constructor(config: ConnectionConfig) {
super(config)
}
getAuthHeaders(): Record<string, string> {
return {
Authorization: 'Basic user:password',
}
}
handleResponse<Entity>(jsonResponse: unknown): Promise<Entity> {
// Do something with the response, like modifying the data
// By default here is where the response is flattened
}
request<Entity>(path: string, requestOptions: RequestOptions): Promise<Entity> {
// Use your custom request library, like axios
}
}
API
Manager
new Manager(options: ConnectionConfig, requestService?: RequestService)
Creates a new Manager
instance.
ConnectionConfig
is an object with the following properties:
Property | Type | Description | Required | Default |
---|---|---|---|---|
baseUrl | string | Base url of the Strapi API | true | |
accessToken | string | Access token of the Strapi API | true | |
flatten | boolean | Flatten the response from the Strapi API, removing the attributes and data properties | false | false |
manager.getRepository(target: Entity): Repository<Entity>
:
Returns a new Repository instance for the given entity.
Repository
repository.find(): Promise<Entity[]>
repository.findBy(where: FindOptionsWhere<Entity>): Promise<Entity[]>
repository.findOneById(id: number | string): Promise<Entity>
repository.findOneBy(where: FindOptionsWhere<Entity>): Promise<Entity[]>
repository.create(entity: Entity): Promise<Entity>
repository.update(id: number | string, entity: Entity): Promise<Entity>
repository.delete(id: number | string): Promise<Entity>
repository.createQueryBuilder(): StrapiQueryBuilder<Entity>
QueryBuilder
queryBuilder.select(fields: string | string[]): SelectQueryBuilder<Entity>
queryBuilder.populate(relation: string, fields?: string | string[], filter?: StrapiFilter, sort?: StrapiSort): SelectQueryBuilder<Entity>
queryBuilder.where(field: string, filters: StrapiFilter): SelectQueryBuilder<Entity>
queryBuilder.getMany(): Promise<Entity[]>
queryBuilder.getOne(): Promise<Entity>
4 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago