@tanglemedia/svelte-starter-directus-api 6.0.2 → 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 +42 -24
- package/dist/adapter/api-adapter.js +134 -72
- 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 -3
- 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 +18 -21
- package/src/adapter/api-adapter.ts +257 -115
- package/src/index.ts +1 -0
- package/src/provider/api-adapter.provider.ts +11 -3
- package/src/provider/api-references-functions.provider.ts +261 -200
- 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,31 +22,28 @@
|
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@directus/types": "
|
|
26
|
-
"@sveltejs/adapter-auto": "^
|
|
27
|
-
"@sveltejs/package": "^2.
|
|
28
|
-
"@sveltejs/vite-plugin-svelte": "^
|
|
29
|
-
"@
|
|
30
|
-
"@testing-library/
|
|
31
|
-
"@
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"svelte
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"@tanglemedia/svelte-starter-core": "2.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",
|
|
49
|
-
"@tanglemedia/svelte-starter-core": ">=
|
|
46
|
+
"@tanglemedia/svelte-starter-core": ">=3.0.0",
|
|
50
47
|
"svelte": "^4.0.0 || >=5.0.0"
|
|
51
48
|
},
|
|
52
49
|
"scripts": {
|
|
@@ -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,25 +22,49 @@ 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';
|
|
39
|
+
|
|
40
|
+
type PathKey<Schema extends SchemaShape> = Extract<RegularCollections<Schema>, string>;
|
|
41
|
+
|
|
42
|
+
export type AdapterClient<Schema extends SchemaShape = SchemaShape> = DirectusAdapterClient<Schema>;
|
|
43
|
+
|
|
44
|
+
const allowedQueryKeys = [
|
|
45
|
+
'fields',
|
|
46
|
+
'sort',
|
|
47
|
+
'filter',
|
|
48
|
+
'limit',
|
|
49
|
+
'offset',
|
|
50
|
+
'page',
|
|
51
|
+
'search',
|
|
52
|
+
'version',
|
|
53
|
+
'versionRaw',
|
|
54
|
+
'export',
|
|
55
|
+
'group',
|
|
56
|
+
'aggregate',
|
|
57
|
+
'deep',
|
|
58
|
+
'alias'
|
|
59
|
+
] as const;
|
|
60
|
+
|
|
61
|
+
type Q = Record<string, unknown>;
|
|
33
62
|
|
|
34
|
-
export type AdapterClient<Schema extends SchemaShape = SchemaShape> = DirectusClient<Schema> &
|
|
35
|
-
RestClient<Schema>;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* TODO: Various types fixes. The current adapter doesn't correctly follow the types defined under the ApiAdapterAbstract.
|
|
39
|
-
* See the fetch adapter under the core
|
|
40
|
-
*/
|
|
41
63
|
export class DirectusApiAdapter<
|
|
42
64
|
Schema extends SchemaShape = SchemaShape,
|
|
43
|
-
Path extends
|
|
65
|
+
Path extends PathKey<Schema> = PathKey<Schema>
|
|
44
66
|
>
|
|
45
|
-
extends ApiAdapterAbstract<DirectusConfig, ApiAdapterRequestConfig, Path, AdapterClient
|
|
67
|
+
extends ApiAdapterAbstract<DirectusConfig, ApiAdapterRequestConfig, Path, AdapterClient<Schema>>
|
|
46
68
|
implements ApiAdapterHandle
|
|
47
69
|
{
|
|
48
70
|
constructor(
|
|
@@ -53,8 +75,7 @@ export class DirectusApiAdapter<
|
|
|
53
75
|
}
|
|
54
76
|
|
|
55
77
|
async handle(event: HandleEvent) {
|
|
56
|
-
|
|
57
|
-
this.directus.globals.fetch = f;
|
|
78
|
+
this.directus.globals.fetch = event.fetch;
|
|
58
79
|
}
|
|
59
80
|
|
|
60
81
|
getAdapterClient(): AdapterClient<Schema> | null {
|
|
@@ -65,51 +86,60 @@ export class DirectusApiAdapter<
|
|
|
65
86
|
const payload = response.data,
|
|
66
87
|
meta = response.meta as Record<string, unknown>;
|
|
67
88
|
|
|
68
|
-
if (!meta) {
|
|
69
|
-
return {};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (typeof meta.total === 'undefined') {
|
|
89
|
+
if (!meta || typeof meta.total === 'undefined') {
|
|
73
90
|
return {};
|
|
74
91
|
}
|
|
75
92
|
|
|
76
93
|
const displayed = Array.isArray(payload) ? payload.length : 0;
|
|
77
|
-
|
|
78
94
|
const total = Number(meta.total);
|
|
79
95
|
|
|
80
|
-
// todo: Transform or attempt to get meta information
|
|
81
|
-
// consider pulling count based on existing filters in order to determine pagination
|
|
82
96
|
return { total, displayed };
|
|
83
97
|
}
|
|
84
98
|
|
|
85
|
-
|
|
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> {
|
|
86
116
|
if (true !== this.config.configuration.includeTotals) {
|
|
87
117
|
return null;
|
|
88
118
|
}
|
|
89
119
|
|
|
90
120
|
const { filter, search } = query || {};
|
|
91
|
-
|
|
121
|
+
const override = config?.configuration as Partial<DirectusApiAdapterOptions> | undefined;
|
|
92
122
|
// default to count. Note that there is a bug in directus where
|
|
93
123
|
// the wrong counts are being returned if there are nested filters.
|
|
94
124
|
// A quick fix is to set totalAggregate to countDistinct
|
|
95
|
-
const k = this.config.configuration.totalAggregate || 'count';
|
|
96
|
-
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');
|
|
97
127
|
|
|
98
|
-
const data = await this.directus.request(
|
|
99
|
-
aggregate(collection
|
|
128
|
+
const data = await this.directus.request<Array<Record<string, unknown>>>(
|
|
129
|
+
aggregate(collection as unknown as AllCollections<Schema>, {
|
|
100
130
|
aggregate: { [k]: f },
|
|
101
131
|
query: {
|
|
102
132
|
...(filter ? { filter } : {}),
|
|
103
133
|
...(search ? { search } : {})
|
|
104
134
|
}
|
|
105
|
-
})
|
|
135
|
+
} as never)
|
|
106
136
|
);
|
|
107
137
|
|
|
108
138
|
let total = 0;
|
|
109
139
|
|
|
110
140
|
if (data && data.length === 1) {
|
|
111
141
|
const c = data[0][k];
|
|
112
|
-
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);
|
|
113
143
|
}
|
|
114
144
|
|
|
115
145
|
return isNaN(total) ? 0 : total;
|
|
@@ -118,157 +148,269 @@ export class DirectusApiAdapter<
|
|
|
118
148
|
async transformResponse<T, M extends object = AnyObject>(
|
|
119
149
|
res: { data: T; meta?: AnyObject },
|
|
120
150
|
status: number = 200
|
|
121
|
-
): Promise<ApiResponse<T,
|
|
151
|
+
): Promise<ApiResponse<T, null, M>> {
|
|
122
152
|
return {
|
|
123
|
-
body: await this.envelopeResponse<T, M>(
|
|
153
|
+
body: (await this.envelopeResponse<T, M>(
|
|
124
154
|
res.data,
|
|
125
155
|
(res.meta ? this.normalizeMeta(res as AnyObject) : {}) as M
|
|
126
|
-
),
|
|
127
|
-
status
|
|
156
|
+
)) as ApiResponse<T, null, M>['body'],
|
|
157
|
+
status,
|
|
128
158
|
statusText: 'OK',
|
|
129
159
|
headers: {},
|
|
130
160
|
adapterResponse: null
|
|
131
161
|
};
|
|
132
162
|
}
|
|
133
163
|
|
|
134
|
-
|
|
135
|
-
const
|
|
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
|
+
(acc, k) => (typeof c[k] !== 'undefined' ? ((acc[k] = c[k]), acc) : acc),
|
|
169
|
+
{}
|
|
170
|
+
);
|
|
136
171
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
...
|
|
140
|
-
|
|
172
|
+
return {
|
|
173
|
+
...q,
|
|
174
|
+
...r,
|
|
175
|
+
...(merge || {})
|
|
141
176
|
};
|
|
177
|
+
}
|
|
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
|
+
}
|
|
142
186
|
|
|
143
|
-
|
|
187
|
+
if (q && (typeof q.id === 'string' || typeof q.id === 'number')) {
|
|
188
|
+
return q.id;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return null;
|
|
144
192
|
}
|
|
145
193
|
|
|
146
|
-
|
|
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>(
|
|
147
210
|
method: BaseApiMethods,
|
|
148
|
-
url:
|
|
149
|
-
query?:
|
|
150
|
-
): Promise<
|
|
211
|
+
url: Path,
|
|
212
|
+
query?: ApiAdapterRequestConfig
|
|
213
|
+
): Promise<ApiResponse<R>> {
|
|
151
214
|
try {
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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);
|
|
160
237
|
} catch (error) {
|
|
161
238
|
console.error(`Error request:`, error);
|
|
162
239
|
throw error;
|
|
163
240
|
}
|
|
164
241
|
}
|
|
165
242
|
|
|
166
|
-
public async find<T,
|
|
243
|
+
public async find<T, F = T, R = T>(
|
|
167
244
|
collection: Path,
|
|
168
|
-
query: ApiFindQuery<
|
|
245
|
+
query: ApiFindQuery<F>,
|
|
246
|
+
config?: ApiAdapterRequestConfig
|
|
169
247
|
): Promise<ApiResponse<R[]>> {
|
|
170
|
-
const
|
|
171
|
-
const
|
|
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
|
+
|
|
172
254
|
if (null === total) {
|
|
173
|
-
return this.transformResponse({ data
|
|
255
|
+
return this.transformResponse({ data });
|
|
174
256
|
}
|
|
175
|
-
// console.log('find meta', response, total)
|
|
176
257
|
|
|
177
|
-
return this.transformResponse({ data
|
|
258
|
+
return this.transformResponse({ data, meta: { total } });
|
|
178
259
|
}
|
|
179
260
|
|
|
180
|
-
public async findOne<T>(
|
|
261
|
+
public async findOne<T, R = T>(
|
|
181
262
|
collection: Path,
|
|
182
|
-
key
|
|
183
|
-
query?:
|
|
184
|
-
): Promise<ApiResponse<
|
|
185
|
-
const
|
|
263
|
+
key: ApiId,
|
|
264
|
+
query?: ApiAdapterRequestConfig
|
|
265
|
+
): Promise<ApiResponse<R>> {
|
|
266
|
+
const q = this.normalizeQuery(query);
|
|
267
|
+
const data = await this.directus.request<R>(
|
|
268
|
+
readItem(collection as unknown as RegularCollections<Schema>, key, q as never)
|
|
269
|
+
);
|
|
186
270
|
return this.transformResponse({ data });
|
|
187
271
|
}
|
|
188
272
|
|
|
189
|
-
public async aggregate<T,
|
|
273
|
+
public async aggregate<T, F = T, R = T>(
|
|
190
274
|
collection: Path,
|
|
191
|
-
query: ApiAggregateQuery<
|
|
275
|
+
query: ApiAggregateQuery<F>,
|
|
276
|
+
config?: ApiAdapterRequestConfig
|
|
192
277
|
): Promise<ApiResponse<R>> {
|
|
193
|
-
const { aggregate:
|
|
194
|
-
|
|
195
|
-
const data = await this.directus.request<
|
|
196
|
-
aggregate(collection
|
|
197
|
-
aggregate:
|
|
198
|
-
? aggregate_
|
|
199
|
-
: {
|
|
200
|
-
count: 'id'
|
|
201
|
-
},
|
|
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' },
|
|
202
283
|
query: rest
|
|
203
|
-
})
|
|
284
|
+
} as never)
|
|
204
285
|
);
|
|
205
286
|
|
|
206
287
|
return this.transformResponse({ data });
|
|
207
288
|
}
|
|
208
289
|
|
|
209
|
-
public async patch<T>(
|
|
290
|
+
public async patch<T extends object, R = T>(
|
|
210
291
|
collection: Path,
|
|
211
292
|
key: ApiId,
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
293
|
+
data: ApiPatchQuery<T>,
|
|
294
|
+
config?: ApiAdapterRequestConfig
|
|
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 });
|
|
216
301
|
}
|
|
217
302
|
|
|
218
|
-
public async post<T>(
|
|
303
|
+
public async post<T extends object, R = T>(
|
|
219
304
|
collection: Path,
|
|
220
|
-
data:
|
|
221
|
-
|
|
222
|
-
): Promise<ApiResponse<
|
|
223
|
-
const
|
|
224
|
-
|
|
305
|
+
data: ApiPostQuery<T>,
|
|
306
|
+
config?: ApiAdapterRequestConfig
|
|
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);
|
|
225
313
|
}
|
|
226
314
|
|
|
227
|
-
public async delete<T
|
|
228
|
-
|
|
315
|
+
public async delete<T, R = T>(
|
|
316
|
+
collection: Path,
|
|
317
|
+
key: ApiId,
|
|
318
|
+
config?: ApiAdapterRequestConfig
|
|
319
|
+
): Promise<ApiResponse<R>> {
|
|
320
|
+
void config;
|
|
321
|
+
const data = await this.directus.request<R>(deleteItem(collection as never, key));
|
|
229
322
|
return this.transformResponse({ data }, 202);
|
|
230
323
|
}
|
|
231
324
|
|
|
232
325
|
public async put<T extends object, R = T>(
|
|
233
326
|
collection: Path,
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
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
|
|
237
341
|
): Promise<ApiResponse<R>> {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
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) {
|
|
245
356
|
throw new Error('No key specified');
|
|
246
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);
|
|
247
364
|
}
|
|
248
365
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
366
|
+
public async upload<T, R = T>(
|
|
367
|
+
path: Path,
|
|
368
|
+
data: FormData,
|
|
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);
|
|
253
375
|
}
|
|
254
376
|
|
|
255
|
-
async createMany<T, R = T>(
|
|
256
|
-
|
|
257
|
-
|
|
377
|
+
async createMany<T, R = T>(
|
|
378
|
+
path: Path,
|
|
379
|
+
body: ApiCreateManyQuery<T>,
|
|
380
|
+
config?: ApiAdapterRequestConfig
|
|
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);
|
|
258
387
|
}
|
|
259
388
|
|
|
260
|
-
async updateMany<T, R = T>(
|
|
389
|
+
async updateMany<T, R = T>(
|
|
390
|
+
path: Path,
|
|
391
|
+
body: ApiUpdateManyQuery<T>,
|
|
392
|
+
config?: ApiAdapterRequestConfig
|
|
393
|
+
): Promise<ApiResponse<R[]>> {
|
|
261
394
|
if (!body.ids) {
|
|
262
395
|
throw Error('You must provide an array of keys to update');
|
|
263
396
|
}
|
|
264
|
-
|
|
265
|
-
|
|
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)
|
|
266
402
|
);
|
|
267
|
-
return this.transformResponse
|
|
403
|
+
return this.transformResponse({ data }, 200);
|
|
268
404
|
}
|
|
269
405
|
|
|
270
|
-
async deleteMany<R
|
|
271
|
-
|
|
272
|
-
|
|
406
|
+
async deleteMany<R>(
|
|
407
|
+
path: Path,
|
|
408
|
+
body: ApiDeleteManyQuery<ApiId>,
|
|
409
|
+
config?: ApiAdapterRequestConfig
|
|
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);
|
|
273
415
|
}
|
|
274
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
|
}
|