@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.
@@ -1,12 +1,10 @@
1
- import { type AllCollections, type DirectusClient, type RegularCollections, type RestClient } from '@directus/sdk';
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
- export type AdapterClient<Schema extends SchemaShape = SchemaShape> = DirectusClient<Schema> & RestClient<Schema>;
5
- /**
6
- * TODO: Various types fixes. The current adapter doesn't correctly follow the types defined under the ApiAdapterAbstract.
7
- * See the fetch adapter under the core
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,22 +17,42 @@ export declare class DirectusApiAdapter<Schema extends SchemaShape = SchemaShape
19
17
  total: number;
20
18
  displayed: number;
21
19
  };
22
- includeTotals(collection: AllCollections<Schema>, query?: ApiFindQuery<any>): Promise<number | null>;
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, Response, M>>;
27
- getConfig(configuration?: unknown): DirectusConfig;
28
- request<T>(method: BaseApiMethods, url: string, query?: Record<string, unknown>): Promise<T>;
29
- find<T, Q = T, R = T>(collection: Path, query: ApiFindQuery<Q>): Promise<ApiResponse<R[]>>;
30
- findOne<T>(collection: Path, key?: ApiId, query?: Record<string, unknown>): Promise<ApiResponse<T>>;
31
- aggregate<T, Q = T, R = T>(collection: Path, query: ApiAggregateQuery<Q>): Promise<ApiResponse<R>>;
32
- patch<T>(collection: Path, key: ApiId, query?: Record<string, unknown>): Promise<ApiResponse<T>>;
33
- post<T>(collection: Path, data: AnyObject, query?: Record<string, unknown>): Promise<ApiResponse<T>>;
34
- delete<T>(collection: Path, key?: ApiId): Promise<ApiResponse<T>>;
35
- put<T extends object, R = T>(collection: Path, key?: ApiId, payload?: AnyObject, query?: Record<string, unknown>): Promise<ApiResponse<R>>;
36
- upload<T>(path: string | undefined, data: FormData): Promise<ApiResponse<T>>;
37
- createMany<T, R = T>(path: Path, body: ApiCreateManyQuery<T>): Promise<ApiResponse<R[], Response, AnyObject>>;
38
- updateMany<T, R = T>(path: Path, body: ApiUpdateManyQuery<T>): Promise<ApiResponse<R[], Response, AnyObject>>;
39
- deleteMany<R = null>(path: Path, body: ApiDeleteManyQuery<ApiId>): Promise<ApiResponse<R, Response, AnyObject>>;
36
+ }, status?: number): Promise<ApiResponse<T, null, M>>;
37
+ normalizeQuery(config?: ApiAdapterRequestConfig, merge?: Q): {
38
+ [x: string]: unknown;
39
+ };
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[]>>;
40
57
  }
58
+ export {};
@@ -1,9 +1,21 @@
1
1
  import { aggregate, createItem, createItems, deleteItem, deleteItems, readItem, readItems, updateItem, updateItems, uploadFiles } from '@directus/sdk';
2
2
  import { ApiAdapterAbstract } from '@tanglemedia/svelte-starter-core';
3
- /**
4
- * TODO: Various types fixes. The current adapter doesn't correctly follow the types defined under the ApiAdapterAbstract.
5
- * See the fetch adapter under the core
6
- */
3
+ const allowedQueryKeys = [
4
+ 'fields',
5
+ 'sort',
6
+ 'filter',
7
+ 'limit',
8
+ 'offset',
9
+ 'page',
10
+ 'search',
11
+ 'version',
12
+ 'versionRaw',
13
+ 'export',
14
+ 'group',
15
+ 'aggregate',
16
+ 'deep',
17
+ 'alias'
18
+ ];
7
19
  export class DirectusApiAdapter extends ApiAdapterAbstract {
8
20
  config;
9
21
  directus;
@@ -13,36 +25,43 @@ export class DirectusApiAdapter extends ApiAdapterAbstract {
13
25
  this.directus = directus;
14
26
  }
15
27
  async handle(event) {
16
- const f = event.fetch;
17
- this.directus.globals.fetch = f;
28
+ this.directus.globals.fetch = event.fetch;
18
29
  }
19
30
  getAdapterClient() {
20
31
  return this.directus;
21
32
  }
22
33
  normalizeMeta(response) {
23
34
  const payload = response.data, meta = response.meta;
24
- if (!meta) {
25
- return {};
26
- }
27
- if (typeof meta.total === 'undefined') {
35
+ if (!meta || typeof meta.total === 'undefined') {
28
36
  return {};
29
37
  }
30
38
  const displayed = Array.isArray(payload) ? payload.length : 0;
31
39
  const total = Number(meta.total);
32
- // todo: Transform or attempt to get meta information
33
- // consider pulling count based on existing filters in order to determine pagination
34
40
  return { total, displayed };
35
41
  }
36
- async includeTotals(collection, query) {
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) {
37
55
  if (true !== this.config.configuration.includeTotals) {
38
56
  return null;
39
57
  }
40
58
  const { filter, search } = query || {};
59
+ const override = config?.configuration;
41
60
  // default to count. Note that there is a bug in directus where
42
61
  // the wrong counts are being returned if there are nested filters.
43
62
  // A quick fix is to set totalAggregate to countDistinct
44
- const k = this.config.configuration.totalAggregate || 'count';
45
- 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');
46
65
  const data = await this.directus.request(aggregate(collection, {
47
66
  aggregate: { [k]: f },
48
67
  query: {
@@ -59,103 +78,146 @@ export class DirectusApiAdapter extends ApiAdapterAbstract {
59
78
  }
60
79
  async transformResponse(res, status = 200) {
61
80
  return {
62
- body: await this.envelopeResponse(res.data, (res.meta ? this.normalizeMeta(res) : {})),
63
- status: status,
81
+ body: (await this.envelopeResponse(res.data, (res.meta ? this.normalizeMeta(res) : {}))),
82
+ status,
64
83
  statusText: 'OK',
65
84
  headers: {},
66
85
  adapterResponse: null
67
86
  };
68
87
  }
69
- getConfig(configuration) {
70
- const client = this.directus;
71
- // Add the 'configuration' property to the returned object
72
- const config = {
73
- ...this.config,
74
- configuration: configuration ?? this.config.configuration ?? {} // Use the provided configuration or an empty object if not provided
88
+ normalizeQuery(config = {}, merge) {
89
+ const q = { ...(config?.params || {}) };
90
+ const c = { ...config };
91
+ const r = allowedQueryKeys.reduce((acc, k) => (typeof c[k] !== 'undefined' ? ((acc[k] = c[k]), acc) : acc), {});
92
+ return {
93
+ ...q,
94
+ ...r,
95
+ ...(merge || {})
96
+ };
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
75
118
  };
76
- return Object.assign(client, config);
77
119
  }
78
120
  async request(method, url, query) {
79
121
  try {
80
- const response = await this.directus.request(() => {
81
- const params = JSON.stringify(query);
82
- return {
83
- path: `${url}?${params}`,
84
- method: method
85
- };
86
- });
87
- return response;
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);
88
138
  }
89
139
  catch (error) {
90
140
  console.error(`Error request:`, error);
91
141
  throw error;
92
142
  }
93
143
  }
94
- async find(collection, query) {
95
- const response = (await this.directus.request(readItems(collection, query)));
96
- const total = await this.includeTotals(collection, query);
144
+ async find(collection, query, config) {
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);
97
148
  if (null === total) {
98
- return this.transformResponse({ data: response });
149
+ return this.transformResponse({ data });
99
150
  }
100
- // console.log('find meta', response, total)
101
- return this.transformResponse({ data: response, meta: { total } });
151
+ return this.transformResponse({ data, meta: { total } });
102
152
  }
103
153
  async findOne(collection, key, query) {
104
- const data = await this.directus.request(readItem(collection, key, query));
154
+ const q = this.normalizeQuery(query);
155
+ const data = await this.directus.request(readItem(collection, key, q));
105
156
  return this.transformResponse({ data });
106
157
  }
107
- async aggregate(collection, query) {
108
- const { aggregate: aggregate_, ...rest } = query || {};
158
+ async aggregate(collection, query, config) {
159
+ const { aggregate: a, ...rest } = this.normalizeQuery(config, query);
109
160
  const data = await this.directus.request(aggregate(collection, {
110
- aggregate: aggregate_
111
- ? aggregate_
112
- : {
113
- count: 'id'
114
- },
161
+ aggregate: a ? a : { count: 'id' },
115
162
  query: rest
116
163
  }));
117
164
  return this.transformResponse({ data });
118
165
  }
119
- async patch(collection, key, query) {
120
- const data = await this.directus.request(updateItem(collection, key, query));
121
- return this.transformResponse({ data });
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 });
122
170
  }
123
- async post(collection, data, query) {
124
- const response = await this.directus.request(createItem(collection, data, query));
125
- return this.transformResponse({ data: response }, 201);
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);
126
175
  }
127
- async delete(collection, key) {
176
+ async delete(collection, key, config) {
177
+ void config;
128
178
  const data = await this.directus.request(deleteItem(collection, key));
129
179
  return this.transformResponse({ data }, 202);
130
180
  }
131
- async put(collection, key, payload, query) {
132
- if (key) {
133
- const data = (await this.directus.request(updateItem(collection, key, payload, query)));
134
- return this.transformResponse({ data }, 201);
135
- }
136
- else {
137
- console.error(`Error updating all ${collection}: no key specified`);
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) {
138
192
  throw new Error('No key specified');
139
193
  }
140
- }
141
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
142
- async upload(path = '', data) {
143
- const response = await this.directus.request(uploadFiles(data));
144
- return this.transformResponse({ data: response }, 201);
145
- }
146
- async createMany(path, body) {
147
- const data = await this.directus.request(createItems(path, body.data, body?.query));
194
+ const res = await this.directus.request(updateItem(collection, key, data, this.normalizeQuery(this.stripId(q))));
195
+ return this.transformResponse({ data: res }, 201);
196
+ }
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);
202
+ }
203
+ async createMany(path, body, config) {
204
+ const q = this.normalizeQuery(config, body.query || {});
205
+ const data = await this.directus.request(createItems(path, body.data, q));
148
206
  return this.transformResponse({ data }, 200);
149
207
  }
150
- async updateMany(path, body) {
208
+ async updateMany(path, body, config) {
151
209
  if (!body.ids) {
152
210
  throw Error('You must provide an array of keys to update');
153
211
  }
154
- const data = await this.directus.request(updateItems(path, body.ids || [], body.data, body?.query));
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));
155
215
  return this.transformResponse({ data }, 200);
156
216
  }
157
- async deleteMany(path, body) {
158
- const data = await this.directus.request(deleteItems(path, body.ids));
217
+ async deleteMany(path, body, config) {
218
+ void config;
219
+ const ids = body.ids;
220
+ const data = await this.directus.request(deleteItems(path, ids));
159
221
  return this.transformResponse({ data }, 201);
160
222
  }
161
223
  }
package/dist/index.d.ts CHANGED
@@ -4,3 +4,4 @@ export * from './services/auth';
4
4
  export * from './services/register';
5
5
  export type * from './types';
6
6
  export * from './provider/api-references-functions.provider';
7
+ export * from './utils/directus-error';
package/dist/index.js CHANGED
@@ -3,3 +3,4 @@ export * from './provider/directus.factory';
3
3
  export * from './services/auth';
4
4
  export * from './services/register';
5
5
  export * from './provider/api-references-functions.provider';
6
+ export * from './utils/directus-error';
@@ -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 object>(config: DirectusConfig): import("@directus/sdk").DirectusClient<T> & import("@directus/sdk").RestClient<T>;
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 { readItem, readSingleton, readItems, createItem, createItems, updateItem, updateSingleton, updateItems, deleteItem, deleteItems, readAssetRaw, readFiles, readFile, uploadFiles, importFile, updateFile, updateFiles, deleteFile, deleteFiles, readActivities, readActivity, readCollections, readCollection, createCollection, updateCollection, deleteCollection, readComments, readComment, createComment, createComments, updateComment, updateComments, deleteComment, deleteComments, readContentVersions, readContentVersion, createContentVersion, createContentVersions, updateContentVersion, updateContentVersions, deleteContentVersion, deleteContentVersions, saveToContentVersion, compareContentVersion, promoteContentVersion, readDashboards, readDashboard, createDashboard, createDashboards, updateDashboard, updateDashboards, deleteDashboard, deleteDashboards, readExtensions, updateExtension, readFields, readFieldsByCollection, readField, createField, updateField, deleteField, readFlows, readFlow, createFlow, createFlows, updateFlow, updateFlows, deleteFlow, deleteFlows, triggerFlow, readFolders, readFolder, createFolder, createFolders, updateFolder, updateFolders, deleteFolder, deleteFolders, readNotifications, readNotification, createNotification, createNotifications, updateNotification, updateNotifications, deleteNotification, deleteNotifications, readOperations, readOperation, createOperation, createOperations, updateOperation, updateOperations, deleteOperation, deleteOperations, readPanels, readPanel, createPanel, createPanels, updatePanel, updatePanels, deletePanel, deletePanels, readPermissions, readPermission, createPermission, createPermissions, updatePermission, updatePermissions, deletePermission, deletePermissions, readUserPermissions, readItemPermissions, readPolicies, readPolicy, createPolicy, createPolicies, updatePolicy, updatePolicies, deletePolicy, deletePolicies, readPresets, readPreset, createPreset, createPresets, updatePreset, updatePresets, deletePreset, deletePresets, readRelations, readRelationByCollection, readRelation, createRelation, updateRelation, deleteRelation, readRevisions, readRevision, readRoles, readRole, createRole, createRoles, updateRole, updateRoles, deleteRole, deleteRoles, schemaSnapshot, readOpenApiSpec, readGraphqlSdl, serverPing, serverInfo, serverHealth, readSettings, updateSettings, readShares, readShare, createShare, createShares, updateShare, updateShares, deleteShare, deleteShares, authenticateShare, inviteShare, readShareInfo, readTranslations, readTranslation, createTranslation, createTranslations, updateTranslation, updateTranslations, deleteTranslation, deleteTranslations, readUsers, readUser, readMe, updateMe, createUser, createUsers, updateUser, updateUsers, deleteUser, deleteUsers, registerUser, registerUserVerify, inviteUser, acceptUserInvite, generateTwoFactorSecret, enableTwoFactor, disableTwoFactor, randomString, generateHash, verifyHash, utilitySort, utilsImport, utilsExport, clearCache, passwordRequest, createDirectus, rest, staticToken } from '@directus/sdk';
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,3 +1,18 @@
1
- export { readItem, readSingleton, readItems, createItem, createItems, updateItem, updateSingleton, updateItems, deleteItem, deleteItems, readAssetRaw, readFiles, readFile, uploadFiles, importFile, updateFile, updateFiles, deleteFile, deleteFiles, readActivities, readActivity, readCollections, readCollection, createCollection, updateCollection, deleteCollection, readComments, readComment, createComment, createComments, updateComment, updateComments, deleteComment, deleteComments, readContentVersions, readContentVersion, createContentVersion, createContentVersions, updateContentVersion, updateContentVersions, deleteContentVersion, deleteContentVersions, saveToContentVersion, compareContentVersion, promoteContentVersion, readDashboards, readDashboard, createDashboard, createDashboards, updateDashboard, updateDashboards, deleteDashboard,
2
- // triggerOperation
3
- deleteDashboards, readExtensions, updateExtension, readFields, readFieldsByCollection, readField, createField, updateField, deleteField, readFlows, readFlow, createFlow, createFlows, updateFlow, updateFlows, deleteFlow, deleteFlows, triggerFlow, readFolders, readFolder, createFolder, createFolders, updateFolder, updateFolders, deleteFolder, deleteFolders, readNotifications, readNotification, createNotification, createNotifications, updateNotification, updateNotifications, deleteNotification, deleteNotifications, readOperations, readOperation, createOperation, createOperations, updateOperation, updateOperations, deleteOperation, deleteOperations, readPanels, readPanel, createPanel, createPanels, updatePanel, updatePanels, deletePanel, deletePanels, readPermissions, readPermission, createPermission, createPermissions, updatePermission, updatePermissions, deletePermission, deletePermissions, readUserPermissions, readItemPermissions, readPolicies, readPolicy, createPolicy, createPolicies, updatePolicy, updatePolicies, deletePolicy, deletePolicies, readPresets, readPreset, createPreset, createPresets, updatePreset, updatePresets, deletePreset, deletePresets, readRelations, readRelationByCollection, readRelation, createRelation, updateRelation, deleteRelation, readRevisions, readRevision, readRoles, readRole, createRole, createRoles, updateRole, updateRoles, deleteRole, deleteRoles, schemaSnapshot, readOpenApiSpec, readGraphqlSdl, serverPing, serverInfo, serverHealth, readSettings, updateSettings, readShares, readShare, createShare, createShares, updateShare, updateShares, deleteShare, deleteShares, authenticateShare, inviteShare, readShareInfo, readTranslations, readTranslation, createTranslation, createTranslations, updateTranslation, updateTranslations, deleteTranslation, deleteTranslations, readUsers, readUser, readMe, updateMe, createUser, createUsers, updateUser, updateUsers, deleteUser, deleteUsers, registerUser, registerUserVerify, inviteUser, acceptUserInvite, generateTwoFactorSecret, enableTwoFactor, disableTwoFactor, randomString, generateHash, verifyHash, utilitySort, utilsImport, utilsExport, clearCache, passwordRequest, createDirectus, rest, staticToken } from '@directus/sdk';
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 object>({ baseUrl, configuration: { protocol, host, auth, staticToken: token, graphql: gql, rest: rs } }: DirectusConfig, options?: ClientOptions) => import("@directus/sdk").DirectusClient<T> & import("@directus/sdk").RestClient<T>;
6
+ export declare const createDirectusClientFactory: <T extends SchemaShape>({ baseUrl, configuration: { protocol, host, auth, staticToken: token, graphql: gql, rest: rs } }: DirectusConfig, options?: ClientOptions) => DirectusAdapterClient<T>;
@@ -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<DirectusClient<object> & RestClient<object> & AuthenticationClient<object>>;
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>;
@@ -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.getDirectus()).refresh();
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.getDirectus()).getToken();
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.getDirectus()).login(email, password);
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.getDirectus()).logout();
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 response = await (await this.getDirectus()).request(readMe({ fields: fields ? fields : ['*', 'roles.*'] }));
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 successfully registered your account', type: 'success' };
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 { type AllCollections, type DirectusClient, type RegularCollections, type RestClient, type StaticTokenClient, type AuthenticationClient } from '@directus/sdk';
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 {} from '@directus/sdk';
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
+ }