@tsed/directus-sdk 8.19.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.
- package/.barrelsby.json +5 -0
- package/lib/esm/bootstrap/attach-logger.js +25 -0
- package/lib/esm/bootstrap/runtime.js +11 -0
- package/lib/esm/decorators/cache.js +60 -0
- package/lib/esm/fn/defineEndpoint.js +82 -0
- package/lib/esm/fn/defineHook.js +134 -0
- package/lib/esm/fn/defineOperationApi.js +120 -0
- package/lib/esm/fn/wrapEndpoint.js +80 -0
- package/lib/esm/fn/wrapOperation.js +63 -0
- package/lib/esm/index.js +14 -0
- package/lib/esm/services/DirectusCacheInterceptor.js +184 -0
- package/lib/esm/services/DirectusContextService.js +162 -0
- package/lib/esm/services/DirectusItemsRepository.js +240 -0
- package/lib/types/bootstrap/attach-logger.d.ts +1 -0
- package/lib/types/bootstrap/runtime.d.ts +1 -0
- package/lib/types/decorators/cache.d.ts +57 -0
- package/lib/types/fn/defineEndpoint.d.ts +73 -0
- package/lib/types/fn/defineHook.d.ts +105 -0
- package/lib/types/fn/defineOperationApi.d.ts +114 -0
- package/lib/types/fn/wrapEndpoint.d.ts +35 -0
- package/lib/types/fn/wrapOperation.d.ts +35 -0
- package/lib/types/index.d.ts +14 -0
- package/lib/types/services/DirectusCacheInterceptor.d.ts +154 -0
- package/lib/types/services/DirectusContextService.d.ts +149 -0
- package/lib/types/services/DirectusItemsRepository.d.ts +226 -0
- package/package.json +63 -0
- package/readme.md +493 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import type { Item, MutationOptions } from "@directus/types";
|
|
2
|
+
import { DirectusContextService } from "./DirectusContextService.js";
|
|
3
|
+
/**
|
|
4
|
+
* Abstract base class for creating typed repository patterns with Directus collections.
|
|
5
|
+
*
|
|
6
|
+
* This class provides a structured way to interact with Directus collections by:
|
|
7
|
+
* - Automatically retrieving the Directus context via dependency injection
|
|
8
|
+
* - Providing common CRUD operations (create, update, listAll)
|
|
9
|
+
* - Supporting custom methods through inheritance
|
|
10
|
+
* - Ensuring type safety with TypeScript generics
|
|
11
|
+
*
|
|
12
|
+
* Extend this class to create collection-specific repositories with custom business logic.
|
|
13
|
+
*
|
|
14
|
+
* ### Basic repository with custom methods
|
|
15
|
+
* ```ts
|
|
16
|
+
* import {injectable} from "@tsed/di";
|
|
17
|
+
* import {DirectusItemsRepository} from "@tsed/directus-sdk";
|
|
18
|
+
* import type {Item} from "@directus/types";
|
|
19
|
+
*
|
|
20
|
+
* type Release = Item & {
|
|
21
|
+
* id: string;
|
|
22
|
+
* title: string;
|
|
23
|
+
* status: "draft" | "published";
|
|
24
|
+
* publishedAt?: string;
|
|
25
|
+
* };
|
|
26
|
+
*
|
|
27
|
+
* export class ReleasesRepository extends DirectusItemsRepository<Release, "releases"> {
|
|
28
|
+
* protected collection = "releases" as const;
|
|
29
|
+
*
|
|
30
|
+
* async getPublishedReleases() {
|
|
31
|
+
* const collection = await this.getCollection();
|
|
32
|
+
*
|
|
33
|
+
* return collection.readByQuery({
|
|
34
|
+
* filter: {
|
|
35
|
+
* status: {
|
|
36
|
+
* _eq: "published"
|
|
37
|
+
* }
|
|
38
|
+
* },
|
|
39
|
+
* sort: ["-publishedAt"]
|
|
40
|
+
* });
|
|
41
|
+
* }
|
|
42
|
+
*
|
|
43
|
+
* async publishRelease(id: string) {
|
|
44
|
+
* return this.update({
|
|
45
|
+
* id,
|
|
46
|
+
* status: "published",
|
|
47
|
+
* publishedAt: new Date().toISOString()
|
|
48
|
+
* });
|
|
49
|
+
* }
|
|
50
|
+
* }
|
|
51
|
+
* injectable(ReleasesRepository)
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* ### Repository with complex queries
|
|
55
|
+
*
|
|
56
|
+
* ```ts
|
|
57
|
+
* import {injectable} from "@tsed/di";
|
|
58
|
+
* import {DirectusItemsRepository} from "@tsed/directus-sdk";
|
|
59
|
+
*
|
|
60
|
+
* export class ArticlesRepository extends DirectusItemsRepository<Article, "articles"> {
|
|
61
|
+
* protected collection = "articles" as const;
|
|
62
|
+
*
|
|
63
|
+
* async findByAuthor(authorId: string) {
|
|
64
|
+
* const collection = await this.getCollection();
|
|
65
|
+
*
|
|
66
|
+
* return collection.readByQuery({
|
|
67
|
+
* filter: {
|
|
68
|
+
* author: {
|
|
69
|
+
* _eq: authorId
|
|
70
|
+
* }
|
|
71
|
+
* }
|
|
72
|
+
* });
|
|
73
|
+
* }
|
|
74
|
+
*
|
|
75
|
+
* async searchByTitle(query: string) {
|
|
76
|
+
* const collection = await this.getCollection();
|
|
77
|
+
*
|
|
78
|
+
* return collection.readByQuery({
|
|
79
|
+
* filter: {
|
|
80
|
+
* title: {
|
|
81
|
+
* _contains: query
|
|
82
|
+
* }
|
|
83
|
+
* }
|
|
84
|
+
* });
|
|
85
|
+
* }
|
|
86
|
+
* }
|
|
87
|
+
* injectable(ArticlesRepository);
|
|
88
|
+
* ```
|
|
89
|
+
*
|
|
90
|
+
* ### Using repository in an endpoint
|
|
91
|
+
*
|
|
92
|
+
* ```ts
|
|
93
|
+
* import {defineEndpoint} from "@tsed/directus-sdk";
|
|
94
|
+
* import {inject} from "@tsed/di";
|
|
95
|
+
*
|
|
96
|
+
* export default defineEndpoint({
|
|
97
|
+
* id: "releases-api",
|
|
98
|
+
* handler: (router) => {
|
|
99
|
+
* const releasesRepo = inject(ReleasesRepository);
|
|
100
|
+
*
|
|
101
|
+
* router.get("/releases", async (req, res) => {
|
|
102
|
+
* const releases = await releasesRepo.getPublishedReleases();
|
|
103
|
+
* res.json(releases);
|
|
104
|
+
* });
|
|
105
|
+
*
|
|
106
|
+
* router.post("/releases/:id/publish", async (req, res) => {
|
|
107
|
+
* const release = await releasesRepo.publishRelease(req.params.id);
|
|
108
|
+
* res.json(release);
|
|
109
|
+
* });
|
|
110
|
+
* }
|
|
111
|
+
* });
|
|
112
|
+
* ```
|
|
113
|
+
*
|
|
114
|
+
* @template T - The item type extending Directus Item interface
|
|
115
|
+
* @template Collection - The collection name as a string literal type
|
|
116
|
+
*
|
|
117
|
+
* @remarks
|
|
118
|
+
* - The extending class must define the `collection` property
|
|
119
|
+
* - Don't forget to mark the extending class with `@Injectable()` or `injectable()`
|
|
120
|
+
* - Access to Directus context is automatically handled through `DirectusContextService`
|
|
121
|
+
*
|
|
122
|
+
* @see {@link DirectusContextService} for lower-level access to Directus context
|
|
123
|
+
*/
|
|
124
|
+
export declare abstract class DirectusItemsRepository<T extends Item = Item, Collection extends string = string> {
|
|
125
|
+
protected contextService: DirectusContextService;
|
|
126
|
+
protected abstract collection: Collection;
|
|
127
|
+
/**
|
|
128
|
+
* Retrieves the Directus ItemsService for the configured collection.
|
|
129
|
+
*
|
|
130
|
+
* This method provides access to the underlying Directus ItemsService,
|
|
131
|
+
* which offers full CRUD capabilities and advanced query features.
|
|
132
|
+
*
|
|
133
|
+
* ```ts
|
|
134
|
+
* const collection = await this.getCollection();
|
|
135
|
+
* const items = await collection.readByQuery({
|
|
136
|
+
* filter: { status: { _eq: "active" } },
|
|
137
|
+
* limit: 10,
|
|
138
|
+
* offset: 0
|
|
139
|
+
* });
|
|
140
|
+
* ```
|
|
141
|
+
*
|
|
142
|
+
* @returns A promise resolving to the ItemsService for the collection
|
|
143
|
+
*
|
|
144
|
+
*/
|
|
145
|
+
getCollection(): Promise<import("@directus/types").AbstractService<T>>;
|
|
146
|
+
/**
|
|
147
|
+
* Creates a new item in the collection and returns the created item.
|
|
148
|
+
*
|
|
149
|
+
* ```ts
|
|
150
|
+
* const newRelease = await releasesRepo.create({
|
|
151
|
+
* title: "Version 1.0",
|
|
152
|
+
* status: "draft"
|
|
153
|
+
* });
|
|
154
|
+
*
|
|
155
|
+
* console.log(newRelease.id); // Auto-generated ID
|
|
156
|
+
* ```
|
|
157
|
+
*
|
|
158
|
+
* ### With mutation options
|
|
159
|
+
*
|
|
160
|
+
* ```ts
|
|
161
|
+
* const item = await repo.create(data, {
|
|
162
|
+
* emitEvents: false,
|
|
163
|
+
* bypassLimits: true
|
|
164
|
+
* });
|
|
165
|
+
* ```
|
|
166
|
+
*
|
|
167
|
+
* @param data - Partial item data to create
|
|
168
|
+
* @param opts - Optional mutation options (e.g., emitEvents, bypassLimits)
|
|
169
|
+
*
|
|
170
|
+
* @returns A promise resolving to the created item with all fields
|
|
171
|
+
*/
|
|
172
|
+
create(data: Partial<T>, opts?: MutationOptions): Promise<T>;
|
|
173
|
+
/**
|
|
174
|
+
* Updates an existing item in the collection and returns the updated item.
|
|
175
|
+
*
|
|
176
|
+
* ```ts
|
|
177
|
+
* const updated = await releasesRepo.update({
|
|
178
|
+
* id: "release-123",
|
|
179
|
+
* status: "published"
|
|
180
|
+
* });
|
|
181
|
+
* ```
|
|
182
|
+
*
|
|
183
|
+
* ### With mutation options
|
|
184
|
+
*
|
|
185
|
+
* ```ts
|
|
186
|
+
* const updated = await repo.update(
|
|
187
|
+
* { id: "123", title: "New Title" },
|
|
188
|
+
* { emitEvents: true }
|
|
189
|
+
* );
|
|
190
|
+
* ```
|
|
191
|
+
*
|
|
192
|
+
* @param data - Partial item data including the required `id` field
|
|
193
|
+
* @param opts - Optional mutation options (e.g., emitEvents, bypassLimits)
|
|
194
|
+
*
|
|
195
|
+
* @returns A promise resolving to the updated item
|
|
196
|
+
*/
|
|
197
|
+
update(data: Partial<T> & Pick<T, "id">, opts?: MutationOptions): Promise<T>;
|
|
198
|
+
/**
|
|
199
|
+
* Retrieves all items from the collection without pagination.
|
|
200
|
+
*
|
|
201
|
+
* ```ts
|
|
202
|
+
* const allReleases = await releasesRepo.listAll();
|
|
203
|
+
* console.log(`Total releases: ${allReleases.length}`);
|
|
204
|
+
* ```
|
|
205
|
+
*
|
|
206
|
+
* ### For large collections, consider custom pagination
|
|
207
|
+
*
|
|
208
|
+
* ```ts
|
|
209
|
+
* async getPaginatedItems(page: number, pageSize: number) {
|
|
210
|
+
* const collection = await this.getCollection();
|
|
211
|
+
* return collection.readByQuery({
|
|
212
|
+
* limit: pageSize,
|
|
213
|
+
* offset: (page - 1) * pageSize
|
|
214
|
+
* });
|
|
215
|
+
* }
|
|
216
|
+
* ```
|
|
217
|
+
*
|
|
218
|
+
* @returns A promise resolving to an array of all items in the collection
|
|
219
|
+
*
|
|
220
|
+
* @remarks
|
|
221
|
+
* This method uses `limit: -1` to retrieve all items. Use with caution on
|
|
222
|
+
* large collections as it may impact performance.
|
|
223
|
+
*
|
|
224
|
+
*/
|
|
225
|
+
listAll(): Promise<T[]>;
|
|
226
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tsed/directus-sdk",
|
|
3
|
+
"description": "A library to integrate Directus SDK with Ts.ED, facilitating the creation of extensions (endpoints, hooks, operations) and the use of Directus services.",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"version": "8.19.0",
|
|
6
|
+
"source": "./src/index.ts",
|
|
7
|
+
"main": "./lib/esm/index.js",
|
|
8
|
+
"module": "./lib/esm/index.js",
|
|
9
|
+
"typings": "./lib/types/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"tsed-source": "./src/index.ts",
|
|
13
|
+
"types": "./lib/types/index.d.ts",
|
|
14
|
+
"import": "./lib/esm/index.js",
|
|
15
|
+
"default": "./lib/esm/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./attach-logger": {
|
|
18
|
+
"tsed-source": "./src/bootstrap/attach-logger.ts",
|
|
19
|
+
"types": "./lib/types/bootstrap/attach-logger.d.ts",
|
|
20
|
+
"import": "./lib/esm/bootstrap/attach-logger.js",
|
|
21
|
+
"default": "./lib/esm/bootstrap/attach-logger.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "yarn barrels && yarn build:ts",
|
|
26
|
+
"barrels": "barrels",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"build:ts": "tsc --build tsconfig.esm.json",
|
|
29
|
+
"test:ci": "vitest run --coverage.thresholds.autoUpdate=true"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"semver": "^7.6.3",
|
|
33
|
+
"tslib": "2.8.1"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@directus/api": "32.1.0",
|
|
37
|
+
"@directus/extensions-sdk": "13.1.1",
|
|
38
|
+
"@directus/sdk": "20.2.0",
|
|
39
|
+
"@directus/types": "13.4.0",
|
|
40
|
+
"@tsed/barrels": "8.19.0",
|
|
41
|
+
"@tsed/logger-connect": "8.0.4",
|
|
42
|
+
"vitest": "3.2.4"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@directus/api": ">=31.0.0",
|
|
46
|
+
"@directus/extensions-sdk": ">=13.0.0",
|
|
47
|
+
"@directus/sdk": ">=20.0.0",
|
|
48
|
+
"@directus/types": ">=13.0.0",
|
|
49
|
+
"@tsed/config": ">=8.0.0",
|
|
50
|
+
"@tsed/core": ">=8.0.0",
|
|
51
|
+
"@tsed/di": ">=8.0.0",
|
|
52
|
+
"@tsed/logger": ">=8.0.0",
|
|
53
|
+
"@tsed/logger-connect": ">=8.0.0",
|
|
54
|
+
"express": "*"
|
|
55
|
+
},
|
|
56
|
+
"repository": "https://github.com/tsedio/tsed",
|
|
57
|
+
"bugs": {
|
|
58
|
+
"url": "https://github.com/tsedio/tsed/issues"
|
|
59
|
+
},
|
|
60
|
+
"homepage": "https://github.com/tsedio/tsed/tree/production/packages/third-parties/directus-sdk",
|
|
61
|
+
"author": "Romain Lenzotti",
|
|
62
|
+
"license": "MIT"
|
|
63
|
+
}
|