@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.
@@ -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,25 +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
- 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
- request<T>(method: BaseApiMethods, url: string, query?: ApiAdapterRequestConfig): Promise<T>;
32
- find<T, Q = T, R = T>(collection: Path, query: ApiFindQuery<Q>, config?: ApiAdapterRequestConfig): Promise<ApiResponse<R[]>>;
33
- findOne<T>(collection: Path, key?: ApiId, query?: ApiAdapterRequestConfig): Promise<ApiResponse<T>>;
34
- aggregate<T, Q = T, R = T>(collection: Path, query: ApiAggregateQuery<Q>, config?: ApiAdapterRequestConfig): Promise<ApiResponse<R>>;
35
- patch<T>(collection: Path, key: ApiId, query?: Record<string, unknown>, config?: ApiAdapterRequestConfig): Promise<ApiResponse<T>>;
36
- post<T>(collection: Path, data: AnyObject, query?: Record<string, unknown>, config?: ApiAdapterRequestConfig): Promise<ApiResponse<T>>;
37
- delete<T>(collection: Path, key?: ApiId, config?: ApiAdapterRequestConfig): Promise<ApiResponse<T>>;
38
- put<T extends object, R = T>(collection: Path, key?: ApiId, payload?: AnyObject, query?: ApiAdapterRequestConfig): Promise<ApiResponse<R>>;
39
- upload<T>(path: string | undefined, data: FormData, config?: ApiAdapterRequestConfig): Promise<ApiResponse<T>>;
40
- createMany<T, R = T>(path: Path, body: ApiCreateManyQuery<T>, config?: ApiAdapterRequestConfig): Promise<ApiResponse<R[], Response, AnyObject>>;
41
- updateMany<T, R = T>(path: Path, body: ApiUpdateManyQuery<T>, config?: ApiAdapterRequestConfig): Promise<ApiResponse<R[], Response, AnyObject>>;
42
- deleteMany<R = null>(path: Path, body: ApiDeleteManyQuery<ApiId>, config?: ApiAdapterRequestConfig): Promise<ApiResponse<R, Response, AnyObject>>;
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
- const f = event.fetch;
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
- 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) {
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: 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 response = await this.directus.request(() => {
108
- const params = JSON.stringify(query);
109
- return {
110
- path: `${url}?${params}`,
111
- method: method
112
- };
113
- });
114
- 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);
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
- query = this.normalizeQuery(config, query);
123
- const response = (await this.directus.request(readItems(collection, query)));
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: response });
149
+ return this.transformResponse({ data });
127
150
  }
128
- // console.log('find meta', response, total)
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, query));
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: aggregate_, ...rest } = this.normalizeQuery(config, query);
159
+ const { aggregate: a, ...rest } = this.normalizeQuery(config, query);
138
160
  const data = await this.directus.request(aggregate(collection, {
139
- aggregate: 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, query, config) {
149
- const data = await this.directus.request(updateItem(collection, key, query));
150
- 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 });
151
170
  }
152
- async post(collection, data, query, config) {
153
- const response = await this.directus.request(createItem(collection, data, query));
154
- 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);
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, key, payload, query) {
161
- if (key) {
162
- const data = (await this.directus.request(updateItem(collection, key, payload, query)));
163
- return this.transformResponse({ data }, 201);
164
- }
165
- else {
166
- 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) {
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
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
171
- async upload(path = '', data, config) {
172
- const response = await this.directus.request(uploadFiles(data));
173
- return this.transformResponse({ data: response }, 201);
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 data = await this.directus.request(createItems(path, body.data, body?.query));
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 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));
184
215
  return this.transformResponse({ data }, 200);
185
216
  }
186
217
  async deleteMany(path, body, config) {
187
- const data = await this.directus.request(deleteItems(path, body.ids));
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
@@ -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 * 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 +1,18 @@
1
- export * 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
+ }