@tanglemedia/svelte-starter-directus-api 7.0.0 → 8.1.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/dist/adapter/api-adapter.d.ts +40 -25
- package/dist/adapter/api-adapter.js +101 -68
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/provider/api-adapter.provider.d.ts +4 -4
- package/dist/provider/api-references-functions.provider.d.ts +10 -1
- package/dist/provider/api-references-functions.provider.js +18 -1
- package/dist/provider/directus.factory.d.ts +2 -2
- package/dist/services/auth.d.ts +3 -2
- package/dist/services/auth.js +13 -5
- package/dist/services/register.js +1 -1
- package/dist/types/adapter.types.d.ts +5 -3
- package/dist/types/adapter.types.js +1 -1
- package/dist/utils/directus-error.d.ts +6 -0
- package/dist/utils/directus-error.js +42 -0
- package/package.json +17 -20
- package/src/adapter/api-adapter.ts +214 -130
- package/src/index.ts +1 -0
- package/src/provider/api-adapter.provider.ts +11 -3
- package/src/provider/api-references-functions.provider.ts +263 -1
- package/src/provider/directus.factory.ts +7 -7
- package/src/services/auth.ts +21 -11
- package/src/services/register.ts +1 -1
- package/src/types/adapter.types.ts +26 -9
- package/src/utils/directus-error.ts +75 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanglemedia/svelte-starter-directus-api",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.1.0",
|
|
4
4
|
"main": "src/index.ts",
|
|
5
5
|
"types": "src/index.ts",
|
|
6
6
|
"description": "directus API wrapper for all the directus sdk functionality",
|
|
@@ -22,27 +22,24 @@
|
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@directus/types": "
|
|
26
|
-
"@sveltejs/adapter-auto": "^7.0.
|
|
27
|
-
"@sveltejs/package": "^2.5.
|
|
28
|
-
"@sveltejs/vite-plugin-svelte": "^
|
|
29
|
-
"@
|
|
30
|
-
"@testing-library/
|
|
31
|
-
"@
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"svelte
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"@tanglemedia/svelte-starter-core": "3.0.0"
|
|
25
|
+
"@directus/types": "15.0.3",
|
|
26
|
+
"@sveltejs/adapter-auto": "^7.0.1",
|
|
27
|
+
"@sveltejs/package": "^2.5.8",
|
|
28
|
+
"@sveltejs/vite-plugin-svelte": "^7.3.0",
|
|
29
|
+
"@tanglemedia/svelte-starter-core": "3.1.0",
|
|
30
|
+
"@testing-library/jest-dom": "^6.10.0",
|
|
31
|
+
"@testing-library/svelte": "^5.4.2",
|
|
32
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
33
|
+
"jsdom": "^26.1.0",
|
|
34
|
+
"msw": "^2.15.0",
|
|
35
|
+
"svelte": "^5.57.3",
|
|
36
|
+
"svelte-check": "^4.7.7",
|
|
37
|
+
"vite": "^8.3.5",
|
|
38
|
+
"vitest": "^4.1.10"
|
|
40
39
|
},
|
|
41
40
|
"dependencies": {
|
|
42
|
-
"@directus/sdk": "
|
|
43
|
-
"
|
|
44
|
-
"esm-env": "^1.2.2",
|
|
45
|
-
"js-cookie": "^3.0.5"
|
|
41
|
+
"@directus/sdk": "21.3.0",
|
|
42
|
+
"esm-env": "^1.2.2"
|
|
46
43
|
},
|
|
47
44
|
"peerDependencies": {
|
|
48
45
|
"@sveltejs/kit": ">=2 <3",
|
|
@@ -10,9 +10,7 @@ import {
|
|
|
10
10
|
updateItems,
|
|
11
11
|
uploadFiles,
|
|
12
12
|
type AllCollections,
|
|
13
|
-
type
|
|
14
|
-
type RegularCollections,
|
|
15
|
-
type RestClient
|
|
13
|
+
type RegularCollections
|
|
16
14
|
} from '@directus/sdk';
|
|
17
15
|
import {
|
|
18
16
|
ApiAdapterAbstract,
|
|
@@ -24,15 +22,24 @@ import {
|
|
|
24
22
|
type ApiDeleteManyQuery,
|
|
25
23
|
type ApiFindQuery,
|
|
26
24
|
type ApiId,
|
|
25
|
+
type ApiPatchQuery,
|
|
26
|
+
type ApiPostQuery,
|
|
27
|
+
type ApiPutQuery,
|
|
27
28
|
type ApiResponse,
|
|
28
29
|
type ApiUpdateManyQuery,
|
|
29
30
|
type BaseApiMethods,
|
|
30
31
|
type HandleEvent
|
|
31
32
|
} from '@tanglemedia/svelte-starter-core';
|
|
32
|
-
import type {
|
|
33
|
+
import type {
|
|
34
|
+
DirectusAdapterClient,
|
|
35
|
+
DirectusApiAdapterOptions,
|
|
36
|
+
DirectusConfig,
|
|
37
|
+
SchemaShape
|
|
38
|
+
} from '../types/adapter.types';
|
|
33
39
|
|
|
34
|
-
|
|
35
|
-
|
|
40
|
+
type PathKey<Schema extends SchemaShape> = Extract<RegularCollections<Schema>, string>;
|
|
41
|
+
|
|
42
|
+
export type AdapterClient<Schema extends SchemaShape = SchemaShape> = DirectusAdapterClient<Schema>;
|
|
36
43
|
|
|
37
44
|
const allowedQueryKeys = [
|
|
38
45
|
'fields',
|
|
@@ -49,17 +56,15 @@ const allowedQueryKeys = [
|
|
|
49
56
|
'aggregate',
|
|
50
57
|
'deep',
|
|
51
58
|
'alias'
|
|
52
|
-
];
|
|
59
|
+
] as const;
|
|
60
|
+
|
|
61
|
+
type Q = Record<string, unknown>;
|
|
53
62
|
|
|
54
|
-
/**
|
|
55
|
-
* TODO: Various types fixes. The current adapter doesn't correctly follow the types defined under the ApiAdapterAbstract.
|
|
56
|
-
* See the fetch adapter under the core
|
|
57
|
-
*/
|
|
58
63
|
export class DirectusApiAdapter<
|
|
59
64
|
Schema extends SchemaShape = SchemaShape,
|
|
60
|
-
Path extends
|
|
65
|
+
Path extends PathKey<Schema> = PathKey<Schema>
|
|
61
66
|
>
|
|
62
|
-
extends ApiAdapterAbstract<DirectusConfig, ApiAdapterRequestConfig, Path, AdapterClient
|
|
67
|
+
extends ApiAdapterAbstract<DirectusConfig, ApiAdapterRequestConfig, Path, AdapterClient<Schema>>
|
|
63
68
|
implements ApiAdapterHandle
|
|
64
69
|
{
|
|
65
70
|
constructor(
|
|
@@ -70,8 +75,7 @@ export class DirectusApiAdapter<
|
|
|
70
75
|
}
|
|
71
76
|
|
|
72
77
|
async handle(event: HandleEvent) {
|
|
73
|
-
|
|
74
|
-
this.directus.globals.fetch = f;
|
|
78
|
+
this.directus.globals.fetch = event.fetch;
|
|
75
79
|
}
|
|
76
80
|
|
|
77
81
|
getAdapterClient(): AdapterClient<Schema> | null {
|
|
@@ -82,51 +86,60 @@ export class DirectusApiAdapter<
|
|
|
82
86
|
const payload = response.data,
|
|
83
87
|
meta = response.meta as Record<string, unknown>;
|
|
84
88
|
|
|
85
|
-
if (!meta) {
|
|
86
|
-
return {};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
if (typeof meta.total === 'undefined') {
|
|
89
|
+
if (!meta || typeof meta.total === 'undefined') {
|
|
90
90
|
return {};
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
const displayed = Array.isArray(payload) ? payload.length : 0;
|
|
94
|
-
|
|
95
94
|
const total = Number(meta.total);
|
|
96
95
|
|
|
97
|
-
// todo: Transform or attempt to get meta information
|
|
98
|
-
// consider pulling count based on existing filters in order to determine pagination
|
|
99
96
|
return { total, displayed };
|
|
100
97
|
}
|
|
101
98
|
|
|
102
|
-
|
|
99
|
+
/**
|
|
100
|
+
* Counts the items matching the query's `filter` and `search`, or returns `null` when
|
|
101
|
+
* `includeTotals` is not enabled on the adapter. Side effect: sends an aggregate request
|
|
102
|
+
* to Directus.
|
|
103
|
+
*
|
|
104
|
+
* A per-request `config.configuration` can override `totalAggregate` and `totalField`,
|
|
105
|
+
* for example to count a collection whose primary key is not `id`.
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* await adapter.includeTotals('clinics', { filter }, { configuration: { totalField: 'ID' } });
|
|
109
|
+
* // requests aggregate={"countDistinct":"ID"} when the adapter uses countDistinct
|
|
110
|
+
*/
|
|
111
|
+
async includeTotals(
|
|
112
|
+
collection: Path,
|
|
113
|
+
query?: ApiFindQuery<any>,
|
|
114
|
+
config?: ApiAdapterRequestConfig
|
|
115
|
+
): Promise<number | null> {
|
|
103
116
|
if (true !== this.config.configuration.includeTotals) {
|
|
104
117
|
return null;
|
|
105
118
|
}
|
|
106
119
|
|
|
107
120
|
const { filter, search } = query || {};
|
|
108
|
-
|
|
121
|
+
const override = config?.configuration as Partial<DirectusApiAdapterOptions> | undefined;
|
|
109
122
|
// default to count. Note that there is a bug in directus where
|
|
110
123
|
// the wrong counts are being returned if there are nested filters.
|
|
111
124
|
// A quick fix is to set totalAggregate to countDistinct
|
|
112
|
-
const k = this.config.configuration.totalAggregate || 'count';
|
|
113
|
-
const f = this.config.configuration.totalField || 'id';
|
|
125
|
+
const k = override?.totalAggregate ?? (this.config.configuration.totalAggregate || 'count');
|
|
126
|
+
const f = override?.totalField ?? (this.config.configuration.totalField || 'id');
|
|
114
127
|
|
|
115
|
-
const data = await this.directus.request(
|
|
116
|
-
aggregate(collection
|
|
128
|
+
const data = await this.directus.request<Array<Record<string, unknown>>>(
|
|
129
|
+
aggregate(collection as unknown as AllCollections<Schema>, {
|
|
117
130
|
aggregate: { [k]: f },
|
|
118
131
|
query: {
|
|
119
132
|
...(filter ? { filter } : {}),
|
|
120
133
|
...(search ? { search } : {})
|
|
121
134
|
}
|
|
122
|
-
})
|
|
135
|
+
} as never)
|
|
123
136
|
);
|
|
124
137
|
|
|
125
138
|
let total = 0;
|
|
126
139
|
|
|
127
140
|
if (data && data.length === 1) {
|
|
128
141
|
const c = data[0][k];
|
|
129
|
-
total = c && typeof c === 'object' ? Number(c[f]) : Number(c);
|
|
142
|
+
total = c && typeof c === 'object' ? Number((c as Record<string, unknown>)[f]) : Number(c);
|
|
130
143
|
}
|
|
131
144
|
|
|
132
145
|
return isNaN(total) ? 0 : total;
|
|
@@ -135,39 +148,27 @@ export class DirectusApiAdapter<
|
|
|
135
148
|
async transformResponse<T, M extends object = AnyObject>(
|
|
136
149
|
res: { data: T; meta?: AnyObject },
|
|
137
150
|
status: number = 200
|
|
138
|
-
): Promise<ApiResponse<T,
|
|
151
|
+
): Promise<ApiResponse<T, null, M>> {
|
|
139
152
|
return {
|
|
140
|
-
body: await this.envelopeResponse<T, M>(
|
|
153
|
+
body: (await this.envelopeResponse<T, M>(
|
|
141
154
|
res.data,
|
|
142
155
|
(res.meta ? this.normalizeMeta(res as AnyObject) : {}) as M
|
|
143
|
-
),
|
|
144
|
-
status
|
|
156
|
+
)) as ApiResponse<T, null, M>['body'],
|
|
157
|
+
status,
|
|
145
158
|
statusText: 'OK',
|
|
146
159
|
headers: {},
|
|
147
160
|
adapterResponse: null
|
|
148
161
|
};
|
|
149
162
|
}
|
|
150
163
|
|
|
151
|
-
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const config: DirectusConfig = {
|
|
156
|
-
...this.config,
|
|
157
|
-
configuration: configuration ?? this.config.configuration ?? {} // Use the provided configuration or an empty object if not provided
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
return Object.assign(client, config);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
normalizeQuery(config: ApiAdapterRequestConfig = {}, merge?: Record<string, unknown>) {
|
|
164
|
-
const q = { ...(config?.params || {}) };
|
|
165
|
-
const c = { ...config } as Record<string, unknown>;
|
|
166
|
-
// legacy support, this pulls the directus specific keys from the config
|
|
167
|
-
const r = allowedQueryKeys.reduce<Record<string, unknown>>(
|
|
164
|
+
normalizeQuery(config: ApiAdapterRequestConfig = {}, merge?: Q) {
|
|
165
|
+
const q = { ...((config?.params as Q | undefined) || {}) };
|
|
166
|
+
const c = { ...config } as Q;
|
|
167
|
+
const r = allowedQueryKeys.reduce<Q>(
|
|
168
168
|
(acc, k) => (typeof c[k] !== 'undefined' ? ((acc[k] = c[k]), acc) : acc),
|
|
169
169
|
{}
|
|
170
170
|
);
|
|
171
|
+
|
|
171
172
|
return {
|
|
172
173
|
...q,
|
|
173
174
|
...r,
|
|
@@ -175,158 +176,241 @@ export class DirectusApiAdapter<
|
|
|
175
176
|
};
|
|
176
177
|
}
|
|
177
178
|
|
|
178
|
-
|
|
179
|
+
getId(data: object, config?: ApiAdapterRequestConfig): ApiId | null {
|
|
180
|
+
const d = data as Record<string, unknown>;
|
|
181
|
+
const q = config?.params as Q | undefined;
|
|
182
|
+
|
|
183
|
+
if (typeof d.id === 'string' || typeof d.id === 'number') {
|
|
184
|
+
return d.id;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (q && (typeof q.id === 'string' || typeof q.id === 'number')) {
|
|
188
|
+
return q.id;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
stripId(config?: ApiAdapterRequestConfig) {
|
|
195
|
+
const q = config?.params as Q | undefined;
|
|
196
|
+
|
|
197
|
+
if (!q || typeof q.id === 'undefined') {
|
|
198
|
+
return config;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const { id: _id, ...params } = q;
|
|
202
|
+
|
|
203
|
+
return {
|
|
204
|
+
...config,
|
|
205
|
+
params
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
public async request<T, R = T>(
|
|
179
210
|
method: BaseApiMethods,
|
|
180
|
-
url:
|
|
211
|
+
url: Path,
|
|
181
212
|
query?: ApiAdapterRequestConfig
|
|
182
|
-
): Promise<
|
|
213
|
+
): Promise<ApiResponse<R>> {
|
|
183
214
|
try {
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
215
|
+
const { body, headers } = query || {};
|
|
216
|
+
const params = this.normalizeQuery(query);
|
|
217
|
+
|
|
218
|
+
const data = await this.directus.request<R>(
|
|
219
|
+
(() =>
|
|
220
|
+
({
|
|
221
|
+
path: url,
|
|
222
|
+
method,
|
|
223
|
+
headers,
|
|
224
|
+
params,
|
|
225
|
+
...(typeof body === 'undefined'
|
|
226
|
+
? {}
|
|
227
|
+
: {
|
|
228
|
+
body:
|
|
229
|
+
body instanceof FormData || typeof body === 'string'
|
|
230
|
+
? body
|
|
231
|
+
: JSON.stringify(body)
|
|
232
|
+
})
|
|
233
|
+
})) as never
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
return this.transformResponse({ data }, method === 'POST' ? 201 : method === 'DELETE' ? 202 : 200);
|
|
192
237
|
} catch (error) {
|
|
193
238
|
console.error(`Error request:`, error);
|
|
194
239
|
throw error;
|
|
195
240
|
}
|
|
196
241
|
}
|
|
197
242
|
|
|
198
|
-
public async find<T,
|
|
243
|
+
public async find<T, F = T, R = T>(
|
|
199
244
|
collection: Path,
|
|
200
|
-
query: ApiFindQuery<
|
|
245
|
+
query: ApiFindQuery<F>,
|
|
201
246
|
config?: ApiAdapterRequestConfig
|
|
202
247
|
): Promise<ApiResponse<R[]>> {
|
|
203
|
-
|
|
204
|
-
const
|
|
205
|
-
|
|
248
|
+
const q = this.normalizeQuery(config, query as Q);
|
|
249
|
+
const data = await this.directus.request<R[]>(
|
|
250
|
+
readItems(collection as unknown as RegularCollections<Schema>, q as never)
|
|
251
|
+
);
|
|
252
|
+
const total = await this.includeTotals(collection, query, config);
|
|
253
|
+
|
|
206
254
|
if (null === total) {
|
|
207
|
-
return this.transformResponse({ data
|
|
255
|
+
return this.transformResponse({ data });
|
|
208
256
|
}
|
|
209
|
-
// console.log('find meta', response, total)
|
|
210
257
|
|
|
211
|
-
return this.transformResponse({ data
|
|
258
|
+
return this.transformResponse({ data, meta: { total } });
|
|
212
259
|
}
|
|
213
260
|
|
|
214
|
-
public async findOne<T>(
|
|
261
|
+
public async findOne<T, R = T>(
|
|
215
262
|
collection: Path,
|
|
216
|
-
key
|
|
263
|
+
key: ApiId,
|
|
217
264
|
query?: ApiAdapterRequestConfig
|
|
218
|
-
): Promise<ApiResponse<
|
|
265
|
+
): Promise<ApiResponse<R>> {
|
|
219
266
|
const q = this.normalizeQuery(query);
|
|
220
|
-
const data = await this.directus.request<
|
|
267
|
+
const data = await this.directus.request<R>(
|
|
268
|
+
readItem(collection as unknown as RegularCollections<Schema>, key, q as never)
|
|
269
|
+
);
|
|
221
270
|
return this.transformResponse({ data });
|
|
222
271
|
}
|
|
223
272
|
|
|
224
|
-
public async aggregate<T,
|
|
273
|
+
public async aggregate<T, F = T, R = T>(
|
|
225
274
|
collection: Path,
|
|
226
|
-
query: ApiAggregateQuery<
|
|
275
|
+
query: ApiAggregateQuery<F>,
|
|
227
276
|
config?: ApiAdapterRequestConfig
|
|
228
277
|
): Promise<ApiResponse<R>> {
|
|
229
|
-
const { aggregate:
|
|
230
|
-
|
|
231
|
-
const data = await this.directus.request<
|
|
232
|
-
aggregate(collection
|
|
233
|
-
aggregate:
|
|
234
|
-
? aggregate_
|
|
235
|
-
: {
|
|
236
|
-
count: 'id'
|
|
237
|
-
},
|
|
278
|
+
const { aggregate: a, ...rest } = this.normalizeQuery(config, query as Q);
|
|
279
|
+
|
|
280
|
+
const data = await this.directus.request<R>(
|
|
281
|
+
aggregate(collection as unknown as AllCollections<Schema>, {
|
|
282
|
+
aggregate: a ? a : { count: 'id' },
|
|
238
283
|
query: rest
|
|
239
|
-
})
|
|
284
|
+
} as never)
|
|
240
285
|
);
|
|
241
286
|
|
|
242
287
|
return this.transformResponse({ data });
|
|
243
288
|
}
|
|
244
289
|
|
|
245
|
-
public async patch<T>(
|
|
290
|
+
public async patch<T extends object, R = T>(
|
|
246
291
|
collection: Path,
|
|
247
292
|
key: ApiId,
|
|
248
|
-
|
|
293
|
+
data: ApiPatchQuery<T>,
|
|
249
294
|
config?: ApiAdapterRequestConfig
|
|
250
|
-
): Promise<ApiResponse<
|
|
251
|
-
const
|
|
252
|
-
|
|
295
|
+
): Promise<ApiResponse<R>> {
|
|
296
|
+
const q = this.normalizeQuery(config);
|
|
297
|
+
const res = await this.directus.request<R>(
|
|
298
|
+
updateItem(collection as never, key, data as never, q as never)
|
|
299
|
+
);
|
|
300
|
+
return this.transformResponse({ data: res });
|
|
253
301
|
}
|
|
254
302
|
|
|
255
|
-
public async post<T>(
|
|
303
|
+
public async post<T extends object, R = T>(
|
|
256
304
|
collection: Path,
|
|
257
|
-
data:
|
|
258
|
-
query?: Record<string, unknown>,
|
|
305
|
+
data: ApiPostQuery<T>,
|
|
259
306
|
config?: ApiAdapterRequestConfig
|
|
260
|
-
): Promise<ApiResponse<
|
|
261
|
-
const
|
|
262
|
-
|
|
307
|
+
): Promise<ApiResponse<R>> {
|
|
308
|
+
const q = this.normalizeQuery(config);
|
|
309
|
+
const res = await this.directus.request<R>(
|
|
310
|
+
createItem(collection as never, data as never, q as never)
|
|
311
|
+
);
|
|
312
|
+
return this.transformResponse({ data: res }, 201);
|
|
263
313
|
}
|
|
264
314
|
|
|
265
|
-
public async delete<T>(
|
|
315
|
+
public async delete<T, R = T>(
|
|
266
316
|
collection: Path,
|
|
267
|
-
key
|
|
317
|
+
key: ApiId,
|
|
268
318
|
config?: ApiAdapterRequestConfig
|
|
269
|
-
): Promise<ApiResponse<
|
|
270
|
-
|
|
319
|
+
): Promise<ApiResponse<R>> {
|
|
320
|
+
void config;
|
|
321
|
+
const data = await this.directus.request<R>(deleteItem(collection as never, key));
|
|
271
322
|
return this.transformResponse({ data }, 202);
|
|
272
323
|
}
|
|
273
324
|
|
|
274
325
|
public async put<T extends object, R = T>(
|
|
275
326
|
collection: Path,
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
327
|
+
data: ApiPutQuery<T>,
|
|
328
|
+
config?: ApiAdapterRequestConfig
|
|
329
|
+
): Promise<ApiResponse<R>>;
|
|
330
|
+
public async put<T extends object, R = T>(
|
|
331
|
+
collection: Path,
|
|
332
|
+
key: ApiId,
|
|
333
|
+
data?: AnyObject,
|
|
334
|
+
config?: ApiAdapterRequestConfig
|
|
335
|
+
): Promise<ApiResponse<R>>;
|
|
336
|
+
public async put<T extends object, R = T>(
|
|
337
|
+
collection: Path,
|
|
338
|
+
keyOrData: ApiId | ApiPutQuery<T>,
|
|
339
|
+
dataOrConfig?: AnyObject | ApiAdapterRequestConfig,
|
|
340
|
+
config?: ApiAdapterRequestConfig
|
|
279
341
|
): Promise<ApiResponse<R>> {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
342
|
+
const key =
|
|
343
|
+
typeof keyOrData === 'string' || typeof keyOrData === 'number'
|
|
344
|
+
? keyOrData
|
|
345
|
+
: this.getId(keyOrData, dataOrConfig as ApiAdapterRequestConfig | undefined);
|
|
346
|
+
const data =
|
|
347
|
+
typeof keyOrData === 'string' || typeof keyOrData === 'number'
|
|
348
|
+
? (dataOrConfig as AnyObject | undefined)
|
|
349
|
+
: keyOrData;
|
|
350
|
+
const q =
|
|
351
|
+
typeof keyOrData === 'string' || typeof keyOrData === 'number'
|
|
352
|
+
? config
|
|
353
|
+
: (dataOrConfig as ApiAdapterRequestConfig | undefined);
|
|
354
|
+
|
|
355
|
+
if (!key) {
|
|
287
356
|
throw new Error('No key specified');
|
|
288
357
|
}
|
|
358
|
+
|
|
359
|
+
const res = await this.directus.request<R>(
|
|
360
|
+
updateItem(collection as never, key, data as never, this.normalizeQuery(this.stripId(q)) as never)
|
|
361
|
+
);
|
|
362
|
+
|
|
363
|
+
return this.transformResponse({ data: res }, 201);
|
|
289
364
|
}
|
|
290
365
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
path: string = '',
|
|
366
|
+
public async upload<T, R = T>(
|
|
367
|
+
path: Path,
|
|
294
368
|
data: FormData,
|
|
295
|
-
config?: ApiAdapterRequestConfig
|
|
296
|
-
): Promise<ApiResponse<
|
|
297
|
-
|
|
298
|
-
|
|
369
|
+
config?: ApiAdapterRequestConfig & { method?: BaseApiMethods }
|
|
370
|
+
): Promise<ApiResponse<R>> {
|
|
371
|
+
void path;
|
|
372
|
+
void config;
|
|
373
|
+
const res = await this.directus.request<R>(uploadFiles(data));
|
|
374
|
+
return this.transformResponse({ data: res }, 201);
|
|
299
375
|
}
|
|
300
376
|
|
|
301
377
|
async createMany<T, R = T>(
|
|
302
378
|
path: Path,
|
|
303
379
|
body: ApiCreateManyQuery<T>,
|
|
304
380
|
config?: ApiAdapterRequestConfig
|
|
305
|
-
) {
|
|
306
|
-
const
|
|
307
|
-
|
|
381
|
+
): Promise<ApiResponse<R[]>> {
|
|
382
|
+
const q = this.normalizeQuery(config, ((body as Q).query as Q | undefined) || {});
|
|
383
|
+
const data = await this.directus.request<R[]>(
|
|
384
|
+
createItems(path as never, body.data as never, q as never)
|
|
385
|
+
);
|
|
386
|
+
return this.transformResponse({ data }, 200);
|
|
308
387
|
}
|
|
309
388
|
|
|
310
389
|
async updateMany<T, R = T>(
|
|
311
390
|
path: Path,
|
|
312
391
|
body: ApiUpdateManyQuery<T>,
|
|
313
392
|
config?: ApiAdapterRequestConfig
|
|
314
|
-
) {
|
|
393
|
+
): Promise<ApiResponse<R[]>> {
|
|
315
394
|
if (!body.ids) {
|
|
316
395
|
throw Error('You must provide an array of keys to update');
|
|
317
396
|
}
|
|
318
|
-
|
|
319
|
-
|
|
397
|
+
|
|
398
|
+
const q = this.normalizeQuery(config, ((body as Q).query as Q | undefined) || {});
|
|
399
|
+
const ids = body.ids as string[] | number[];
|
|
400
|
+
const data = await this.directus.request<R[]>(
|
|
401
|
+
updateItems(path as never, ids, body.data as never, q as never)
|
|
320
402
|
);
|
|
321
|
-
return this.transformResponse
|
|
403
|
+
return this.transformResponse({ data }, 200);
|
|
322
404
|
}
|
|
323
405
|
|
|
324
|
-
async deleteMany<R
|
|
406
|
+
async deleteMany<R>(
|
|
325
407
|
path: Path,
|
|
326
408
|
body: ApiDeleteManyQuery<ApiId>,
|
|
327
409
|
config?: ApiAdapterRequestConfig
|
|
328
|
-
) {
|
|
329
|
-
|
|
330
|
-
|
|
410
|
+
): Promise<ApiResponse<R[]>> {
|
|
411
|
+
void config;
|
|
412
|
+
const ids = body.ids as string[] | number[];
|
|
413
|
+
const data = await this.directus.request<R[]>(deleteItems(path as never, ids));
|
|
414
|
+
return this.transformResponse({ data }, 201);
|
|
331
415
|
}
|
|
332
416
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
AdapterProviderRegister,
|
|
3
|
+
ApiAdapterRequestConfig,
|
|
3
4
|
ApiAdapterInterface,
|
|
4
5
|
ApiAdapterProviderInterface
|
|
5
6
|
} from '@tanglemedia/svelte-starter-core';
|
|
6
7
|
import { DirectusApiAdapter } from '../adapter/api-adapter';
|
|
7
|
-
import type { DirectusConfig, SchemaShape } from '../types/adapter.types';
|
|
8
|
+
import type { DirectusAdapterClient, DirectusConfig, SchemaShape } from '../types/adapter.types';
|
|
8
9
|
import { createDirectusClientFactory } from './directus.factory';
|
|
9
10
|
|
|
10
11
|
export class DirectusApiProvider implements ApiAdapterProviderInterface<DirectusConfig> {
|
|
11
12
|
async loadAdapter(
|
|
12
13
|
key?: string,
|
|
13
14
|
config?: DirectusConfig
|
|
14
|
-
): Promise<
|
|
15
|
+
): Promise<
|
|
16
|
+
ApiAdapterInterface<
|
|
17
|
+
DirectusConfig,
|
|
18
|
+
ApiAdapterRequestConfig,
|
|
19
|
+
string,
|
|
20
|
+
DirectusAdapterClient<SchemaShape>
|
|
21
|
+
>
|
|
22
|
+
> {
|
|
15
23
|
if (!config) {
|
|
16
24
|
throw new Error('Missing adapter configuration');
|
|
17
25
|
}
|
|
@@ -21,7 +29,7 @@ export class DirectusApiProvider implements ApiAdapterProviderInterface<Directus
|
|
|
21
29
|
return new DirectusApiAdapter(config, client);
|
|
22
30
|
}
|
|
23
31
|
|
|
24
|
-
createDirectusClient<T extends
|
|
32
|
+
createDirectusClient<T extends SchemaShape>(config: DirectusConfig): DirectusAdapterClient<T> {
|
|
25
33
|
// todo: Determine if we can overwrite the fetch globals during runtime
|
|
26
34
|
return createDirectusClientFactory<T>(config);
|
|
27
35
|
}
|