@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
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { ApiAdapterAbstract, type AnyObject, type ApiAdapterHandle, type ApiAdapterRequestConfig, type ApiAggregateQuery, type ApiCreateManyQuery, type ApiDeleteManyQuery, type ApiFindQuery, type ApiId, type ApiResponse, type ApiUpdateManyQuery, type BaseApiMethods, type HandleEvent } from '@tanglemedia/svelte-starter-core';
|
|
3
|
-
import type { DirectusConfig, SchemaShape } from '../types/adapter.types';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
*/
|
|
9
|
-
export declare class DirectusApiAdapter<Schema extends SchemaShape = SchemaShape, Path extends RegularCollections<Schema> = RegularCollections<Schema>> extends ApiAdapterAbstract<DirectusConfig, ApiAdapterRequestConfig, Path, AdapterClient> implements ApiAdapterHandle {
|
|
1
|
+
import { type RegularCollections } from '@directus/sdk';
|
|
2
|
+
import { ApiAdapterAbstract, type AnyObject, type ApiAdapterHandle, type ApiAdapterRequestConfig, type ApiAggregateQuery, type ApiCreateManyQuery, type ApiDeleteManyQuery, type ApiFindQuery, type ApiId, type ApiPatchQuery, type ApiPostQuery, type ApiPutQuery, type ApiResponse, type ApiUpdateManyQuery, type BaseApiMethods, type HandleEvent } from '@tanglemedia/svelte-starter-core';
|
|
3
|
+
import type { DirectusAdapterClient, DirectusConfig, SchemaShape } from '../types/adapter.types';
|
|
4
|
+
type PathKey<Schema extends SchemaShape> = Extract<RegularCollections<Schema>, string>;
|
|
5
|
+
export type AdapterClient<Schema extends SchemaShape = SchemaShape> = DirectusAdapterClient<Schema>;
|
|
6
|
+
type Q = Record<string, unknown>;
|
|
7
|
+
export declare class DirectusApiAdapter<Schema extends SchemaShape = SchemaShape, Path extends PathKey<Schema> = PathKey<Schema>> extends ApiAdapterAbstract<DirectusConfig, ApiAdapterRequestConfig, Path, AdapterClient<Schema>> implements ApiAdapterHandle {
|
|
10
8
|
protected config: DirectusConfig;
|
|
11
9
|
private readonly directus;
|
|
12
10
|
constructor(config: DirectusConfig, directus: AdapterClient<Schema>);
|
|
@@ -19,25 +17,42 @@ export declare class DirectusApiAdapter<Schema extends SchemaShape = SchemaShape
|
|
|
19
17
|
total: number;
|
|
20
18
|
displayed: number;
|
|
21
19
|
};
|
|
22
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Counts the items matching the query's `filter` and `search`, or returns `null` when
|
|
22
|
+
* `includeTotals` is not enabled on the adapter. Side effect: sends an aggregate request
|
|
23
|
+
* to Directus.
|
|
24
|
+
*
|
|
25
|
+
* A per-request `config.configuration` can override `totalAggregate` and `totalField`,
|
|
26
|
+
* for example to count a collection whose primary key is not `id`.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* await adapter.includeTotals('clinics', { filter }, { configuration: { totalField: 'ID' } });
|
|
30
|
+
* // requests aggregate={"countDistinct":"ID"} when the adapter uses countDistinct
|
|
31
|
+
*/
|
|
32
|
+
includeTotals(collection: Path, query?: ApiFindQuery<any>, config?: ApiAdapterRequestConfig): Promise<number | null>;
|
|
23
33
|
transformResponse<T, M extends object = AnyObject>(res: {
|
|
24
34
|
data: T;
|
|
25
35
|
meta?: AnyObject;
|
|
26
|
-
}, status?: number): Promise<ApiResponse<T,
|
|
27
|
-
|
|
28
|
-
normalizeQuery(config?: ApiAdapterRequestConfig, merge?: Record<string, unknown>): {
|
|
36
|
+
}, status?: number): Promise<ApiResponse<T, null, M>>;
|
|
37
|
+
normalizeQuery(config?: ApiAdapterRequestConfig, merge?: Q): {
|
|
29
38
|
[x: string]: unknown;
|
|
30
39
|
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
getId(data: object, config?: ApiAdapterRequestConfig): ApiId | null;
|
|
41
|
+
stripId(config?: ApiAdapterRequestConfig): ApiAdapterRequestConfig | undefined;
|
|
42
|
+
request<T, R = T>(method: BaseApiMethods, url: Path, query?: ApiAdapterRequestConfig): Promise<ApiResponse<R>>;
|
|
43
|
+
find<T, F = T, R = T>(collection: Path, query: ApiFindQuery<F>, config?: ApiAdapterRequestConfig): Promise<ApiResponse<R[]>>;
|
|
44
|
+
findOne<T, R = T>(collection: Path, key: ApiId, query?: ApiAdapterRequestConfig): Promise<ApiResponse<R>>;
|
|
45
|
+
aggregate<T, F = T, R = T>(collection: Path, query: ApiAggregateQuery<F>, config?: ApiAdapterRequestConfig): Promise<ApiResponse<R>>;
|
|
46
|
+
patch<T extends object, R = T>(collection: Path, key: ApiId, data: ApiPatchQuery<T>, config?: ApiAdapterRequestConfig): Promise<ApiResponse<R>>;
|
|
47
|
+
post<T extends object, R = T>(collection: Path, data: ApiPostQuery<T>, config?: ApiAdapterRequestConfig): Promise<ApiResponse<R>>;
|
|
48
|
+
delete<T, R = T>(collection: Path, key: ApiId, config?: ApiAdapterRequestConfig): Promise<ApiResponse<R>>;
|
|
49
|
+
put<T extends object, R = T>(collection: Path, data: ApiPutQuery<T>, config?: ApiAdapterRequestConfig): Promise<ApiResponse<R>>;
|
|
50
|
+
put<T extends object, R = T>(collection: Path, key: ApiId, data?: AnyObject, config?: ApiAdapterRequestConfig): Promise<ApiResponse<R>>;
|
|
51
|
+
upload<T, R = T>(path: Path, data: FormData, config?: ApiAdapterRequestConfig & {
|
|
52
|
+
method?: BaseApiMethods;
|
|
53
|
+
}): Promise<ApiResponse<R>>;
|
|
54
|
+
createMany<T, R = T>(path: Path, body: ApiCreateManyQuery<T>, config?: ApiAdapterRequestConfig): Promise<ApiResponse<R[]>>;
|
|
55
|
+
updateMany<T, R = T>(path: Path, body: ApiUpdateManyQuery<T>, config?: ApiAdapterRequestConfig): Promise<ApiResponse<R[]>>;
|
|
56
|
+
deleteMany<R>(path: Path, body: ApiDeleteManyQuery<ApiId>, config?: ApiAdapterRequestConfig): Promise<ApiResponse<R[]>>;
|
|
43
57
|
}
|
|
58
|
+
export {};
|
|
@@ -16,10 +16,6 @@ const allowedQueryKeys = [
|
|
|
16
16
|
'deep',
|
|
17
17
|
'alias'
|
|
18
18
|
];
|
|
19
|
-
/**
|
|
20
|
-
* TODO: Various types fixes. The current adapter doesn't correctly follow the types defined under the ApiAdapterAbstract.
|
|
21
|
-
* See the fetch adapter under the core
|
|
22
|
-
*/
|
|
23
19
|
export class DirectusApiAdapter extends ApiAdapterAbstract {
|
|
24
20
|
config;
|
|
25
21
|
directus;
|
|
@@ -29,36 +25,43 @@ export class DirectusApiAdapter extends ApiAdapterAbstract {
|
|
|
29
25
|
this.directus = directus;
|
|
30
26
|
}
|
|
31
27
|
async handle(event) {
|
|
32
|
-
|
|
33
|
-
this.directus.globals.fetch = f;
|
|
28
|
+
this.directus.globals.fetch = event.fetch;
|
|
34
29
|
}
|
|
35
30
|
getAdapterClient() {
|
|
36
31
|
return this.directus;
|
|
37
32
|
}
|
|
38
33
|
normalizeMeta(response) {
|
|
39
34
|
const payload = response.data, meta = response.meta;
|
|
40
|
-
if (!meta) {
|
|
41
|
-
return {};
|
|
42
|
-
}
|
|
43
|
-
if (typeof meta.total === 'undefined') {
|
|
35
|
+
if (!meta || typeof meta.total === 'undefined') {
|
|
44
36
|
return {};
|
|
45
37
|
}
|
|
46
38
|
const displayed = Array.isArray(payload) ? payload.length : 0;
|
|
47
39
|
const total = Number(meta.total);
|
|
48
|
-
// todo: Transform or attempt to get meta information
|
|
49
|
-
// consider pulling count based on existing filters in order to determine pagination
|
|
50
40
|
return { total, displayed };
|
|
51
41
|
}
|
|
52
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Counts the items matching the query's `filter` and `search`, or returns `null` when
|
|
44
|
+
* `includeTotals` is not enabled on the adapter. Side effect: sends an aggregate request
|
|
45
|
+
* to Directus.
|
|
46
|
+
*
|
|
47
|
+
* A per-request `config.configuration` can override `totalAggregate` and `totalField`,
|
|
48
|
+
* for example to count a collection whose primary key is not `id`.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* await adapter.includeTotals('clinics', { filter }, { configuration: { totalField: 'ID' } });
|
|
52
|
+
* // requests aggregate={"countDistinct":"ID"} when the adapter uses countDistinct
|
|
53
|
+
*/
|
|
54
|
+
async includeTotals(collection, query, config) {
|
|
53
55
|
if (true !== this.config.configuration.includeTotals) {
|
|
54
56
|
return null;
|
|
55
57
|
}
|
|
56
58
|
const { filter, search } = query || {};
|
|
59
|
+
const override = config?.configuration;
|
|
57
60
|
// default to count. Note that there is a bug in directus where
|
|
58
61
|
// the wrong counts are being returned if there are nested filters.
|
|
59
62
|
// A quick fix is to set totalAggregate to countDistinct
|
|
60
|
-
const k = this.config.configuration.totalAggregate || 'count';
|
|
61
|
-
const f = this.config.configuration.totalField || 'id';
|
|
63
|
+
const k = override?.totalAggregate ?? (this.config.configuration.totalAggregate || 'count');
|
|
64
|
+
const f = override?.totalField ?? (this.config.configuration.totalField || 'id');
|
|
62
65
|
const data = await this.directus.request(aggregate(collection, {
|
|
63
66
|
aggregate: { [k]: f },
|
|
64
67
|
query: {
|
|
@@ -75,26 +78,16 @@ export class DirectusApiAdapter extends ApiAdapterAbstract {
|
|
|
75
78
|
}
|
|
76
79
|
async transformResponse(res, status = 200) {
|
|
77
80
|
return {
|
|
78
|
-
body: await this.envelopeResponse(res.data, (res.meta ? this.normalizeMeta(res) : {})),
|
|
79
|
-
status
|
|
81
|
+
body: (await this.envelopeResponse(res.data, (res.meta ? this.normalizeMeta(res) : {}))),
|
|
82
|
+
status,
|
|
80
83
|
statusText: 'OK',
|
|
81
84
|
headers: {},
|
|
82
85
|
adapterResponse: null
|
|
83
86
|
};
|
|
84
87
|
}
|
|
85
|
-
getConfig(configuration) {
|
|
86
|
-
const client = this.directus;
|
|
87
|
-
// Add the 'configuration' property to the returned object
|
|
88
|
-
const config = {
|
|
89
|
-
...this.config,
|
|
90
|
-
configuration: configuration ?? this.config.configuration ?? {} // Use the provided configuration or an empty object if not provided
|
|
91
|
-
};
|
|
92
|
-
return Object.assign(client, config);
|
|
93
|
-
}
|
|
94
88
|
normalizeQuery(config = {}, merge) {
|
|
95
89
|
const q = { ...(config?.params || {}) };
|
|
96
90
|
const c = { ...config };
|
|
97
|
-
// legacy support, this pulls the directus specific keys from the config
|
|
98
91
|
const r = allowedQueryKeys.reduce((acc, k) => (typeof c[k] !== 'undefined' ? ((acc[k] = c[k]), acc) : acc), {});
|
|
99
92
|
return {
|
|
100
93
|
...q,
|
|
@@ -102,16 +95,46 @@ export class DirectusApiAdapter extends ApiAdapterAbstract {
|
|
|
102
95
|
...(merge || {})
|
|
103
96
|
};
|
|
104
97
|
}
|
|
98
|
+
getId(data, config) {
|
|
99
|
+
const d = data;
|
|
100
|
+
const q = config?.params;
|
|
101
|
+
if (typeof d.id === 'string' || typeof d.id === 'number') {
|
|
102
|
+
return d.id;
|
|
103
|
+
}
|
|
104
|
+
if (q && (typeof q.id === 'string' || typeof q.id === 'number')) {
|
|
105
|
+
return q.id;
|
|
106
|
+
}
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
stripId(config) {
|
|
110
|
+
const q = config?.params;
|
|
111
|
+
if (!q || typeof q.id === 'undefined') {
|
|
112
|
+
return config;
|
|
113
|
+
}
|
|
114
|
+
const { id: _id, ...params } = q;
|
|
115
|
+
return {
|
|
116
|
+
...config,
|
|
117
|
+
params
|
|
118
|
+
};
|
|
119
|
+
}
|
|
105
120
|
async request(method, url, query) {
|
|
106
121
|
try {
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
122
|
+
const { body, headers } = query || {};
|
|
123
|
+
const params = this.normalizeQuery(query);
|
|
124
|
+
const data = await this.directus.request((() => ({
|
|
125
|
+
path: url,
|
|
126
|
+
method,
|
|
127
|
+
headers,
|
|
128
|
+
params,
|
|
129
|
+
...(typeof body === 'undefined'
|
|
130
|
+
? {}
|
|
131
|
+
: {
|
|
132
|
+
body: body instanceof FormData || typeof body === 'string'
|
|
133
|
+
? body
|
|
134
|
+
: JSON.stringify(body)
|
|
135
|
+
})
|
|
136
|
+
})));
|
|
137
|
+
return this.transformResponse({ data }, method === 'POST' ? 201 : method === 'DELETE' ? 202 : 200);
|
|
115
138
|
}
|
|
116
139
|
catch (error) {
|
|
117
140
|
console.error(`Error request:`, error);
|
|
@@ -119,72 +142,82 @@ export class DirectusApiAdapter extends ApiAdapterAbstract {
|
|
|
119
142
|
}
|
|
120
143
|
}
|
|
121
144
|
async find(collection, query, config) {
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
const total = await this.includeTotals(collection, query);
|
|
145
|
+
const q = this.normalizeQuery(config, query);
|
|
146
|
+
const data = await this.directus.request(readItems(collection, q));
|
|
147
|
+
const total = await this.includeTotals(collection, query, config);
|
|
125
148
|
if (null === total) {
|
|
126
|
-
return this.transformResponse({ data
|
|
149
|
+
return this.transformResponse({ data });
|
|
127
150
|
}
|
|
128
|
-
|
|
129
|
-
return this.transformResponse({ data: response, meta: { total } });
|
|
151
|
+
return this.transformResponse({ data, meta: { total } });
|
|
130
152
|
}
|
|
131
153
|
async findOne(collection, key, query) {
|
|
132
154
|
const q = this.normalizeQuery(query);
|
|
133
|
-
const data = await this.directus.request(readItem(collection, key,
|
|
155
|
+
const data = await this.directus.request(readItem(collection, key, q));
|
|
134
156
|
return this.transformResponse({ data });
|
|
135
157
|
}
|
|
136
158
|
async aggregate(collection, query, config) {
|
|
137
|
-
const { aggregate:
|
|
159
|
+
const { aggregate: a, ...rest } = this.normalizeQuery(config, query);
|
|
138
160
|
const data = await this.directus.request(aggregate(collection, {
|
|
139
|
-
aggregate:
|
|
140
|
-
? aggregate_
|
|
141
|
-
: {
|
|
142
|
-
count: 'id'
|
|
143
|
-
},
|
|
161
|
+
aggregate: a ? a : { count: 'id' },
|
|
144
162
|
query: rest
|
|
145
163
|
}));
|
|
146
164
|
return this.transformResponse({ data });
|
|
147
165
|
}
|
|
148
|
-
async patch(collection, key,
|
|
149
|
-
const
|
|
150
|
-
|
|
166
|
+
async patch(collection, key, data, config) {
|
|
167
|
+
const q = this.normalizeQuery(config);
|
|
168
|
+
const res = await this.directus.request(updateItem(collection, key, data, q));
|
|
169
|
+
return this.transformResponse({ data: res });
|
|
151
170
|
}
|
|
152
|
-
async post(collection, data,
|
|
153
|
-
const
|
|
154
|
-
|
|
171
|
+
async post(collection, data, config) {
|
|
172
|
+
const q = this.normalizeQuery(config);
|
|
173
|
+
const res = await this.directus.request(createItem(collection, data, q));
|
|
174
|
+
return this.transformResponse({ data: res }, 201);
|
|
155
175
|
}
|
|
156
176
|
async delete(collection, key, config) {
|
|
177
|
+
void config;
|
|
157
178
|
const data = await this.directus.request(deleteItem(collection, key));
|
|
158
179
|
return this.transformResponse({ data }, 202);
|
|
159
180
|
}
|
|
160
|
-
async put(collection,
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
181
|
+
async put(collection, keyOrData, dataOrConfig, config) {
|
|
182
|
+
const key = typeof keyOrData === 'string' || typeof keyOrData === 'number'
|
|
183
|
+
? keyOrData
|
|
184
|
+
: this.getId(keyOrData, dataOrConfig);
|
|
185
|
+
const data = typeof keyOrData === 'string' || typeof keyOrData === 'number'
|
|
186
|
+
? dataOrConfig
|
|
187
|
+
: keyOrData;
|
|
188
|
+
const q = typeof keyOrData === 'string' || typeof keyOrData === 'number'
|
|
189
|
+
? config
|
|
190
|
+
: dataOrConfig;
|
|
191
|
+
if (!key) {
|
|
167
192
|
throw new Error('No key specified');
|
|
168
193
|
}
|
|
194
|
+
const res = await this.directus.request(updateItem(collection, key, data, this.normalizeQuery(this.stripId(q))));
|
|
195
|
+
return this.transformResponse({ data: res }, 201);
|
|
169
196
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
197
|
+
async upload(path, data, config) {
|
|
198
|
+
void path;
|
|
199
|
+
void config;
|
|
200
|
+
const res = await this.directus.request(uploadFiles(data));
|
|
201
|
+
return this.transformResponse({ data: res }, 201);
|
|
174
202
|
}
|
|
175
203
|
async createMany(path, body, config) {
|
|
176
|
-
const
|
|
204
|
+
const q = this.normalizeQuery(config, body.query || {});
|
|
205
|
+
const data = await this.directus.request(createItems(path, body.data, q));
|
|
177
206
|
return this.transformResponse({ data }, 200);
|
|
178
207
|
}
|
|
179
208
|
async updateMany(path, body, config) {
|
|
180
209
|
if (!body.ids) {
|
|
181
210
|
throw Error('You must provide an array of keys to update');
|
|
182
211
|
}
|
|
183
|
-
const
|
|
212
|
+
const q = this.normalizeQuery(config, body.query || {});
|
|
213
|
+
const ids = body.ids;
|
|
214
|
+
const data = await this.directus.request(updateItems(path, ids, body.data, q));
|
|
184
215
|
return this.transformResponse({ data }, 200);
|
|
185
216
|
}
|
|
186
217
|
async deleteMany(path, body, config) {
|
|
187
|
-
|
|
218
|
+
void config;
|
|
219
|
+
const ids = body.ids;
|
|
220
|
+
const data = await this.directus.request(deleteItems(path, ids));
|
|
188
221
|
return this.transformResponse({ data }, 201);
|
|
189
222
|
}
|
|
190
223
|
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { AdapterProviderRegister, ApiAdapterInterface, ApiAdapterProviderInterface } from '@tanglemedia/svelte-starter-core';
|
|
2
|
-
import type { DirectusConfig } from '../types/adapter.types';
|
|
1
|
+
import type { AdapterProviderRegister, ApiAdapterRequestConfig, ApiAdapterInterface, ApiAdapterProviderInterface } from '@tanglemedia/svelte-starter-core';
|
|
2
|
+
import type { DirectusAdapterClient, DirectusConfig, SchemaShape } from '../types/adapter.types';
|
|
3
3
|
export declare class DirectusApiProvider implements ApiAdapterProviderInterface<DirectusConfig> {
|
|
4
|
-
loadAdapter(key?: string, config?: DirectusConfig): Promise<ApiAdapterInterface<DirectusConfig
|
|
5
|
-
createDirectusClient<T extends
|
|
4
|
+
loadAdapter(key?: string, config?: DirectusConfig): Promise<ApiAdapterInterface<DirectusConfig, ApiAdapterRequestConfig, string, DirectusAdapterClient<SchemaShape>>>;
|
|
5
|
+
createDirectusClient<T extends SchemaShape>(config: DirectusConfig): DirectusAdapterClient<T>;
|
|
6
6
|
}
|
|
7
7
|
export declare const registerDirectusProvider: () => AdapterProviderRegister;
|
|
@@ -1 +1,10 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { authentication, createDirectus, memoryStorage, rest, staticToken } from '@directus/sdk';
|
|
2
|
+
export { login, logout, passwordRequest, passwordReset, readProviders, refresh, } from '@directus/sdk';
|
|
3
|
+
export { createCollection, createComment, createComments, createContentVersion, createContentVersions, createDashboard, createDashboards, createField, createFlow, createFlows, createFolder, createFolders, createItem, createItems, createNotification, createNotifications, createOperation, createOperations, createPanel, createPanels, createPermission, createPermissions, createPolicies, createPolicy, createPreset, createPresets, createRelation, createRole, createRoles, createShare, createShares, createTranslation, createTranslations, createUser, createUsers, importFile, uploadFiles, } from '@directus/sdk';
|
|
4
|
+
export { aggregate, downloadFilesZip, downloadFolderZip, readActivities, readActivity, readAssetArrayBuffer, readAssetBlob, readAssetRaw, readCollection, readCollections, readComment, readComments, readContentVersion, readContentVersions, readDashboard, readDashboards, readExtensions, readField, readFields, readFieldsByCollection, readFile, readFiles, readFlow, readFlows, readFolder, readFolders, readGraphqlSdl, readItem, readItemPermissions, readItems, readMe, readNotification, readNotifications, readOpenApiSpec, readOperation, readOperations, readPanel, readPanels, readPermission, readPermissions, readPolicies, readPolicy, readPolicyGlobals, readPreset, readPresets, readRelation, readRelationByCollection, readRelations, readRevision, readRevisions, readRole, readRoles, readRolesMe, readSettings, readShare, readShareInfo, readShares, readSingleton, readTranslation, readTranslations, readUser, readUserPermissions, readUsers, } from '@directus/sdk';
|
|
5
|
+
export { updateCollection, updateCollectionsBatch, updateComment, updateComments, updateCommentsBatch, updateContentVersion, updateContentVersions, updateContentVersionsBatch, updateDashboard, updateDashboards, updateDashboardsBatch, updateExtension, updateField, updateFields, updateFile, updateFiles, updateFilesBatch, updateFlow, updateFlows, updateFlowsBatch, updateFolder, updateFolders, updateFoldersBatch, updateItem, updateItems, updateItemsBatch, updateMe, updateNotification, updateNotifications, updateNotificationsBatch, updateOperation, updateOperations, updateOperationsBatch, updatePanel, updatePanels, updatePanelsBatch, updatePermission, updatePermissions, updatePermissionsBatch, updatePolicies, updatePoliciesBatch, updatePolicy, updatePreset, updatePresets, updatePresetsBatch, updateRelation, updateRole, updateRoles, updateRolesBatch, updateSettings, updateShare, updateShares, updateSharesBatch, updateSingleton, updateTranslation, updateTranslations, updateTranslationsBatch, updateUser, updateUsers, updateUsersBatch, } from '@directus/sdk';
|
|
6
|
+
export { deleteCollection, deleteComment, deleteComments, deleteContentVersion, deleteContentVersions, deleteDashboard, deleteDashboards, deleteField, deleteFile, deleteFiles, deleteFlow, deleteFlows, deleteFolder, deleteFolders, deleteItem, deleteItems, deleteNotification, deleteNotifications, deleteOperation, deleteOperations, deletePanel, deletePanels, deletePermission, deletePermissions, deletePolicies, deletePolicy, deletePreset, deletePresets, deleteRelation, deleteRole, deleteRoles, deleteShare, deleteShares, deleteTranslation, deleteTranslations, deleteUser, deleteUsers, } from '@directus/sdk';
|
|
7
|
+
export { schemaApply, schemaDiff, schemaSnapshot } from '@directus/sdk';
|
|
8
|
+
export { serverHealth, serverInfo, serverPing } from '@directus/sdk';
|
|
9
|
+
export { acceptUserInvite, authenticateShare, clearCache, compareContentVersion, customEndpoint, disableTwoFactor, enableTwoFactor, generateHash, generateTwoFactorSecret, inviteShare, inviteUser, isDirectusError, promoteContentVersion, randomString, registerUser, registerUserVerify, saveToContentVersion, triggerFlow, utilitySort, utilsExport, utilsImport, verifyHash, withOptions, withSearch, withToken, } from '@directus/sdk';
|
|
10
|
+
export type { DirectusClient, RestClient, RestCommand } from '@directus/sdk';
|
|
@@ -1 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
// Client setup
|
|
2
|
+
export { authentication, createDirectus, memoryStorage, rest, staticToken } from '@directus/sdk';
|
|
3
|
+
// Auth commands
|
|
4
|
+
export { login, logout, passwordRequest, passwordReset, readProviders, refresh, } from '@directus/sdk';
|
|
5
|
+
// Create commands
|
|
6
|
+
export { createCollection, createComment, createComments, createContentVersion, createContentVersions, createDashboard, createDashboards, createField, createFlow, createFlows, createFolder, createFolders, createItem, createItems, createNotification, createNotifications, createOperation, createOperations, createPanel, createPanels, createPermission, createPermissions, createPolicies, createPolicy, createPreset, createPresets, createRelation, createRole, createRoles, createShare, createShares, createTranslation, createTranslations, createUser, createUsers, importFile, uploadFiles, } from '@directus/sdk';
|
|
7
|
+
// Read commands
|
|
8
|
+
export { aggregate, downloadFilesZip, downloadFolderZip, readActivities, readActivity, readAssetArrayBuffer, readAssetBlob, readAssetRaw, readCollection, readCollections, readComment, readComments, readContentVersion, readContentVersions, readDashboard, readDashboards, readExtensions, readField, readFields, readFieldsByCollection, readFile, readFiles, readFlow, readFlows, readFolder, readFolders, readGraphqlSdl, readItem, readItemPermissions, readItems, readMe, readNotification, readNotifications, readOpenApiSpec, readOperation, readOperations, readPanel, readPanels, readPermission, readPermissions, readPolicies, readPolicy, readPolicyGlobals, readPreset, readPresets, readRelation, readRelationByCollection, readRelations, readRevision, readRevisions, readRole, readRoles, readRolesMe, readSettings, readShare, readShareInfo, readShares, readSingleton, readTranslation, readTranslations, readUser, readUserPermissions, readUsers, } from '@directus/sdk';
|
|
9
|
+
// Update commands
|
|
10
|
+
export { updateCollection, updateCollectionsBatch, updateComment, updateComments, updateCommentsBatch, updateContentVersion, updateContentVersions, updateContentVersionsBatch, updateDashboard, updateDashboards, updateDashboardsBatch, updateExtension, updateField, updateFields, updateFile, updateFiles, updateFilesBatch, updateFlow, updateFlows, updateFlowsBatch, updateFolder, updateFolders, updateFoldersBatch, updateItem, updateItems, updateItemsBatch, updateMe, updateNotification, updateNotifications, updateNotificationsBatch, updateOperation, updateOperations, updateOperationsBatch, updatePanel, updatePanels, updatePanelsBatch, updatePermission, updatePermissions, updatePermissionsBatch, updatePolicies, updatePoliciesBatch, updatePolicy, updatePreset, updatePresets, updatePresetsBatch, updateRelation, updateRole, updateRoles, updateRolesBatch, updateSettings, updateShare, updateShares, updateSharesBatch, updateSingleton, updateTranslation, updateTranslations, updateTranslationsBatch, updateUser, updateUsers, updateUsersBatch, } from '@directus/sdk';
|
|
11
|
+
// Delete commands
|
|
12
|
+
export { deleteCollection, deleteComment, deleteComments, deleteContentVersion, deleteContentVersions, deleteDashboard, deleteDashboards, deleteField, deleteFile, deleteFiles, deleteFlow, deleteFlows, deleteFolder, deleteFolders, deleteItem, deleteItems, deleteNotification, deleteNotifications, deleteOperation, deleteOperations, deletePanel, deletePanels, deletePermission, deletePermissions, deletePolicies, deletePolicy, deletePreset, deletePresets, deleteRelation, deleteRole, deleteRoles, deleteShare, deleteShares, deleteTranslation, deleteTranslations, deleteUser, deleteUsers, } from '@directus/sdk';
|
|
13
|
+
// Schema commands
|
|
14
|
+
export { schemaApply, schemaDiff, schemaSnapshot } from '@directus/sdk';
|
|
15
|
+
// Server commands
|
|
16
|
+
export { serverHealth, serverInfo, serverPing } from '@directus/sdk';
|
|
17
|
+
// Utility functions
|
|
18
|
+
export { acceptUserInvite, authenticateShare, clearCache, compareContentVersion, customEndpoint, disableTwoFactor, enableTwoFactor, generateHash, generateTwoFactorSecret, inviteShare, inviteUser, isDirectusError, promoteContentVersion, randomString, registerUser, registerUserVerify, saveToContentVersion, triggerFlow, utilitySort, utilsExport, utilsImport, verifyHash, withOptions, withSearch, withToken, } from '@directus/sdk';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ClientOptions } from '@directus/sdk';
|
|
2
|
-
import type { DirectusConfig } from '../types/adapter.types';
|
|
2
|
+
import type { DirectusAdapterClient, DirectusConfig, SchemaShape } from '../types/adapter.types';
|
|
3
3
|
/**
|
|
4
4
|
* Creates a directus client based on the application configuration
|
|
5
5
|
*/
|
|
6
|
-
export declare const createDirectusClientFactory: <T extends
|
|
6
|
+
export declare const createDirectusClientFactory: <T extends SchemaShape>({ baseUrl, configuration: { protocol, host, auth, staticToken: token, graphql: gql, rest: rs } }: DirectusConfig, options?: ClientOptions) => DirectusAdapterClient<T>;
|
package/dist/services/auth.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { AuthenticationClient, DirectusClient, RestClient } from '@directus/sdk';
|
|
2
1
|
import { ServiceAbstract } from '@tanglemedia/svelte-starter-core';
|
|
2
|
+
import type { DirectusAdapterClient, SchemaShape } from '../types';
|
|
3
3
|
declare class DirectusAuthServices extends ServiceAbstract {
|
|
4
|
-
getDirectus(): Promise<
|
|
4
|
+
getDirectus(): Promise<DirectusAdapterClient<SchemaShape>>;
|
|
5
|
+
private getAuthenticatedDirectus;
|
|
5
6
|
refresh(): Promise<import("@directus/sdk").AuthenticationData>;
|
|
6
7
|
getToken(): Promise<string | null>;
|
|
7
8
|
login(email: string, password: string): Promise<import("@directus/sdk").AuthenticationData>;
|
package/dist/services/auth.js
CHANGED
|
@@ -4,12 +4,19 @@ class DirectusAuthServices extends ServiceAbstract {
|
|
|
4
4
|
getDirectus() {
|
|
5
5
|
return this.getAdapterClient();
|
|
6
6
|
}
|
|
7
|
+
async getAuthenticatedDirectus() {
|
|
8
|
+
const directus = await this.getDirectus();
|
|
9
|
+
if (!directus.refresh || !directus.getToken || !directus.login || !directus.logout) {
|
|
10
|
+
throw new Error('Directus client is missing authentication methods');
|
|
11
|
+
}
|
|
12
|
+
return directus;
|
|
13
|
+
}
|
|
7
14
|
// public getConfig<T extends object>(): DirectusClient<T> & RestClient<object> {
|
|
8
15
|
// return this.directus as DirectusClient<T> & RestClient<object>;
|
|
9
16
|
// }
|
|
10
17
|
async refresh() {
|
|
11
18
|
try {
|
|
12
|
-
const response = await (await this.
|
|
19
|
+
const response = await (await this.getAuthenticatedDirectus()).refresh();
|
|
13
20
|
return response;
|
|
14
21
|
}
|
|
15
22
|
catch (error) {
|
|
@@ -19,7 +26,7 @@ class DirectusAuthServices extends ServiceAbstract {
|
|
|
19
26
|
}
|
|
20
27
|
async getToken() {
|
|
21
28
|
try {
|
|
22
|
-
const response = await (await this.
|
|
29
|
+
const response = await (await this.getAuthenticatedDirectus()).getToken();
|
|
23
30
|
return response;
|
|
24
31
|
}
|
|
25
32
|
catch (error) {
|
|
@@ -29,7 +36,7 @@ class DirectusAuthServices extends ServiceAbstract {
|
|
|
29
36
|
}
|
|
30
37
|
async login(email, password) {
|
|
31
38
|
try {
|
|
32
|
-
const response = await (await this.
|
|
39
|
+
const response = await (await this.getAuthenticatedDirectus()).login({ email, password });
|
|
33
40
|
return response;
|
|
34
41
|
}
|
|
35
42
|
catch (error) {
|
|
@@ -39,7 +46,7 @@ class DirectusAuthServices extends ServiceAbstract {
|
|
|
39
46
|
}
|
|
40
47
|
async logout() {
|
|
41
48
|
try {
|
|
42
|
-
const response = await (await this.
|
|
49
|
+
const response = await (await this.getAuthenticatedDirectus()).logout();
|
|
43
50
|
return response;
|
|
44
51
|
}
|
|
45
52
|
catch (error) {
|
|
@@ -51,7 +58,8 @@ class DirectusAuthServices extends ServiceAbstract {
|
|
|
51
58
|
try {
|
|
52
59
|
if (!(await this.getToken()))
|
|
53
60
|
await this.refresh();
|
|
54
|
-
const
|
|
61
|
+
const queryFields = (fields ?? ['*', 'roles.*']);
|
|
62
|
+
const response = await (await this.getDirectus()).request(readMe({ fields: queryFields }));
|
|
55
63
|
return response;
|
|
56
64
|
}
|
|
57
65
|
catch (error) {
|
|
@@ -7,7 +7,7 @@ class DirectusStaticServices extends ServiceAdapterAbstract {
|
|
|
7
7
|
async createUser(data) {
|
|
8
8
|
try {
|
|
9
9
|
await (await this.getDirectus()).request(createUser(data));
|
|
10
|
-
return { message: 'You have
|
|
10
|
+
return { message: 'You have registered your account', type: 'success' };
|
|
11
11
|
}
|
|
12
12
|
catch (error) {
|
|
13
13
|
console.error(`Error creating a user:`, error);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { AuthenticationMode, GraphqlConfig } from '@directus/sdk';
|
|
1
|
+
import type { AuthenticationClient, AuthenticationMode, DirectusClient, GraphqlClient, GraphqlConfig, RestClient, StaticTokenClient } from '@directus/sdk';
|
|
2
2
|
import type { BaseApiAdapterConfig } from '@tanglemedia/svelte-starter-core';
|
|
3
|
-
export {
|
|
3
|
+
export type { AllCollections, RegularCollections, DirectusClient, RestClient, StaticTokenClient, AuthenticationClient } from '@directus/sdk';
|
|
4
|
+
export type * from '@directus/types';
|
|
4
5
|
export type DirectusApiAuthOptions = {
|
|
5
6
|
mode: AuthenticationMode;
|
|
6
7
|
config?: Partial<{
|
|
@@ -24,4 +25,5 @@ export type DirectusApiAdapterOptions = {
|
|
|
24
25
|
totalField?: string;
|
|
25
26
|
};
|
|
26
27
|
export type DirectusConfig = BaseApiAdapterConfig<DirectusApiAdapterOptions>;
|
|
27
|
-
export type SchemaShape = Record<string, object>;
|
|
28
|
+
export type SchemaShape = Record<string, object | object[]>;
|
|
29
|
+
export type DirectusAdapterClient<Schema extends SchemaShape = SchemaShape> = DirectusClient<Schema> & RestClient<Schema> & Partial<AuthenticationClient<Schema>> & Partial<StaticTokenClient<Schema>> & Partial<GraphqlClient<Schema>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {}
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type DirectusErrorCode = 'FAILED_VALIDATION' | 'FORBIDDEN' | 'INVALID_TOKEN' | 'TOKEN_EXPIRED' | 'INVALID_CREDENTIALS' | 'INVALID_IP' | 'INVALID_OTP' | 'INVALID_PAYLOAD' | 'INVALID_QUERY' | 'UNSUPPORTED_MEDIA_TYPE' | 'REQUESTS_EXCEEDED' | 'ROUTE_NOT_FOUND' | 'SERVICE_UNAVAILABLE' | 'UNPROCESSABLE_CONTENT';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the Directus error code from the first error in a Directus API error response,
|
|
4
|
+
* or null if the value is not a Directus error shape.
|
|
5
|
+
*/
|
|
6
|
+
export declare function extractDirectusErrorCode(err: unknown): DirectusErrorCode | null;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
function parseDirectusErrorCandidate(err) {
|
|
2
|
+
if (typeof err !== 'object' || err === null) {
|
|
3
|
+
return err;
|
|
4
|
+
}
|
|
5
|
+
if (isDirectusErrorShape(err)) {
|
|
6
|
+
return err;
|
|
7
|
+
}
|
|
8
|
+
if (!(err instanceof Error)) {
|
|
9
|
+
return err;
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
return JSON.parse(err.message);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return err;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function isDirectusErrorShape(err) {
|
|
19
|
+
if (typeof err !== 'object' || err === null) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
const candidate = err;
|
|
23
|
+
if (!Array.isArray(candidate['errors']) || candidate['errors'].length === 0) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
const first = candidate['errors'][0];
|
|
27
|
+
return (typeof first['extensions'] === 'object' &&
|
|
28
|
+
first['extensions'] !== null &&
|
|
29
|
+
'code' in first['extensions']);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Returns the Directus error code from the first error in a Directus API error response,
|
|
33
|
+
* or null if the value is not a Directus error shape.
|
|
34
|
+
*/
|
|
35
|
+
export function extractDirectusErrorCode(err) {
|
|
36
|
+
const candidate = parseDirectusErrorCandidate(err);
|
|
37
|
+
if (!isDirectusErrorShape(candidate)) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const code = candidate.errors[0].extensions.code;
|
|
41
|
+
return code ?? null;
|
|
42
|
+
}
|