@svadmin/supabase 0.13.3 → 0.13.5
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/package.json +3 -3
- package/src/supacloud.ts +200 -12
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@svadmin/supabase",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.5",
|
|
4
4
|
"description": "Supabase adapters — DataProvider, AuthProvider, LiveProvider, AuditHandler",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
|
-
"@svadmin/core": "^0.
|
|
27
|
+
"@svadmin/core": "^0.48.0",
|
|
28
28
|
"@supabase/supabase-js": "^2.112.4",
|
|
29
29
|
"@refinedev/supabase": "^6.0.2",
|
|
30
30
|
"@supacloud/js": "^0.23.1"
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
}
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@svadmin/refine-adapter": "^0.10.
|
|
58
|
+
"@svadmin/refine-adapter": "^0.10.12"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@supabase/supabase-js": "^2.112.4"
|
package/src/supacloud.ts
CHANGED
|
@@ -13,7 +13,23 @@ export interface SupaCloudTaskRecord extends TaskRecord {
|
|
|
13
13
|
[key: string]: unknown;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export interface
|
|
16
|
+
export interface SupaCloudTaskReceipt<TTask extends SupaCloudTaskRecord = SupaCloudTaskRecord> {
|
|
17
|
+
id?: string;
|
|
18
|
+
taskId?: string;
|
|
19
|
+
wait(options?: unknown): Promise<TTask>;
|
|
20
|
+
cancel?(): Promise<unknown>;
|
|
21
|
+
retry?(): Promise<unknown>;
|
|
22
|
+
subscribe?(
|
|
23
|
+
options: {
|
|
24
|
+
onUpdate: (task: TTask) => void;
|
|
25
|
+
onStateChange?: (state: unknown, details?: { error?: unknown }) => void;
|
|
26
|
+
onError?: (error: unknown) => void;
|
|
27
|
+
stopOnTerminal?: boolean;
|
|
28
|
+
}
|
|
29
|
+
): TaskSubscription | (() => void) | undefined;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface SupaCloudTaskLegacyClient<TTask extends SupaCloudTaskRecord = SupaCloudTaskRecord> {
|
|
17
33
|
submit(taskName: string, options?: SubmitTaskOptions): Promise<TaskHandle<TTask>>;
|
|
18
34
|
get(taskId: string): Promise<TTask>;
|
|
19
35
|
list?(params?: Record<string, unknown>): Promise<TTask[] | { data?: TTask[] }>;
|
|
@@ -26,6 +42,30 @@ export interface SupaCloudTaskClient<TTask extends SupaCloudTaskRecord = SupaClo
|
|
|
26
42
|
): TaskSubscription | (() => void) | undefined;
|
|
27
43
|
}
|
|
28
44
|
|
|
45
|
+
export interface SupaCloudTaskSdkClient<TTask extends SupaCloudTaskRecord = SupaCloudTaskRecord> {
|
|
46
|
+
tasks: {
|
|
47
|
+
submit(taskName: string, options?: Record<string, unknown>): Promise<SupaCloudTaskReceipt<TTask>>;
|
|
48
|
+
get(taskId: string): Promise<TTask>;
|
|
49
|
+
list?(params?: Record<string, unknown>): Promise<TTask[]>;
|
|
50
|
+
listDlq?(limit?: number): Promise<TTask[]>;
|
|
51
|
+
cancel?(taskId: string): Promise<unknown>;
|
|
52
|
+
retry?(taskId: string): Promise<unknown>;
|
|
53
|
+
subscribe?(
|
|
54
|
+
taskId: string,
|
|
55
|
+
options: {
|
|
56
|
+
onUpdate: (task: TTask) => void;
|
|
57
|
+
onStateChange?: (state: unknown, details?: { error?: unknown }) => void;
|
|
58
|
+
onError?: (error: unknown) => void;
|
|
59
|
+
stopOnTerminal?: boolean;
|
|
60
|
+
}
|
|
61
|
+
): TaskSubscription | (() => void) | undefined;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export type SupaCloudTaskClient<TTask extends SupaCloudTaskRecord = SupaCloudTaskRecord> =
|
|
66
|
+
| SupaCloudTaskLegacyClient<TTask>
|
|
67
|
+
| SupaCloudTaskSdkClient<TTask>;
|
|
68
|
+
|
|
29
69
|
export interface CreateSupaCloudTaskProviderOptions<
|
|
30
70
|
TTask extends SupaCloudTaskRecord = SupaCloudTaskRecord,
|
|
31
71
|
> {
|
|
@@ -35,7 +75,9 @@ export interface CreateSupaCloudTaskProviderOptions<
|
|
|
35
75
|
export interface CreateSupaCloudTaskLiveProviderOptions<
|
|
36
76
|
TTask extends SupaCloudTaskRecord = SupaCloudTaskRecord,
|
|
37
77
|
> {
|
|
38
|
-
supacloud:
|
|
78
|
+
supacloud:
|
|
79
|
+
| Pick<SupaCloudTaskLegacyClient<TTask>, 'subscribe'>
|
|
80
|
+
| SupaCloudTaskSdkClient<TTask>;
|
|
39
81
|
resource?: string;
|
|
40
82
|
mapTaskToEvent?: (task: TTask, resource: string) => LiveEvent;
|
|
41
83
|
}
|
|
@@ -51,14 +93,159 @@ function normalizeTaskSubscription(
|
|
|
51
93
|
return undefined;
|
|
52
94
|
}
|
|
53
95
|
|
|
96
|
+
function normalizeTaskHandle<TTask extends SupaCloudTaskRecord>(
|
|
97
|
+
taskHandle: SupaCloudTaskReceipt<TTask>,
|
|
98
|
+
): TaskHandle<TTask> {
|
|
99
|
+
if (!taskHandle || typeof taskHandle.wait !== 'function') {
|
|
100
|
+
throw new Error('[svadmin/supabase] SupaCloud client returned an invalid task receipt');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const normalized: TaskHandle<TTask> = {
|
|
104
|
+
wait: () => taskHandle.wait(),
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const id = 'taskId' in taskHandle && typeof taskHandle.taskId === 'string'
|
|
108
|
+
? taskHandle.taskId
|
|
109
|
+
: typeof taskHandle.id === 'string'
|
|
110
|
+
? taskHandle.id
|
|
111
|
+
: undefined;
|
|
112
|
+
|
|
113
|
+
if (id) {
|
|
114
|
+
normalized.id = id;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const cancel = taskHandle.cancel;
|
|
118
|
+
if (typeof cancel === 'function') {
|
|
119
|
+
normalized.cancel = () => cancel.call(taskHandle);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const retry = taskHandle.retry;
|
|
123
|
+
if (typeof retry === 'function') {
|
|
124
|
+
normalized.retry = () => retry.call(taskHandle);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const subscribe = taskHandle.subscribe;
|
|
128
|
+
if (typeof subscribe === 'function') {
|
|
129
|
+
normalized.subscribe = (callback) =>
|
|
130
|
+
normalizeTaskSubscription(
|
|
131
|
+
subscribe.call(taskHandle, {
|
|
132
|
+
onUpdate: (task) => callback(task),
|
|
133
|
+
}),
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return normalized;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function mapSubmitOptionsToSdk(
|
|
141
|
+
submitOptions?: SubmitTaskOptions,
|
|
142
|
+
): Record<string, unknown> | undefined {
|
|
143
|
+
if (!submitOptions) return undefined;
|
|
144
|
+
|
|
145
|
+
const sdkOptions: Record<string, unknown> = {};
|
|
146
|
+
|
|
147
|
+
if (submitOptions.body !== undefined) sdkOptions.body = submitOptions.body;
|
|
148
|
+
if (submitOptions.headers !== undefined) sdkOptions.headers = submitOptions.headers;
|
|
149
|
+
if (submitOptions.idempotencyKey !== undefined) sdkOptions.idempotencyKey = submitOptions.idempotencyKey;
|
|
150
|
+
if (submitOptions.meta !== undefined) sdkOptions.metadata = submitOptions.meta;
|
|
151
|
+
|
|
152
|
+
return sdkOptions;
|
|
153
|
+
}
|
|
154
|
+
|
|
54
155
|
function normalizeTaskList<TTask extends SupaCloudTaskRecord>(
|
|
55
156
|
value: TTask[] | { data?: TTask[] },
|
|
157
|
+
context: string,
|
|
56
158
|
): TaskListResult<TTask> {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
159
|
+
if (Array.isArray(value)) {
|
|
160
|
+
return {
|
|
161
|
+
data: value,
|
|
162
|
+
total: value.length,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (value && typeof value === 'object' && Array.isArray(value.data)) {
|
|
167
|
+
return {
|
|
168
|
+
data: value.data,
|
|
169
|
+
total: value.data.length,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
throw new Error(`[svadmin/supabase] ${context} returned an invalid task list response`);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function getTaskBridge<TTask extends SupaCloudTaskRecord>(
|
|
177
|
+
supacloud: SupaCloudTaskClient<TTask>,
|
|
178
|
+
): SupaCloudTaskLegacyClient<TTask> {
|
|
179
|
+
if ('tasks' in supacloud && supacloud.tasks) {
|
|
180
|
+
const sdk = supacloud.tasks;
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
async submit(taskName, submitOptions) {
|
|
184
|
+
const receipt = await sdk.submit(taskName, mapSubmitOptionsToSdk(submitOptions));
|
|
185
|
+
return normalizeTaskHandle(receipt);
|
|
186
|
+
},
|
|
187
|
+
get(taskId) {
|
|
188
|
+
return sdk.get(taskId);
|
|
189
|
+
},
|
|
190
|
+
async list(params) {
|
|
191
|
+
if (!sdk.list) {
|
|
192
|
+
throw new Error('[svadmin/supabase] SupaCloud SDK client does not implement tasks.list');
|
|
193
|
+
}
|
|
194
|
+
return normalizeTaskList(await sdk.list(params), 'tasks.list');
|
|
195
|
+
},
|
|
196
|
+
async listDlq(params) {
|
|
197
|
+
if (!sdk.listDlq) {
|
|
198
|
+
throw new Error('[svadmin/supabase] SupaCloud SDK client does not implement tasks.listDlq');
|
|
199
|
+
}
|
|
200
|
+
const limit = typeof params?.limit === 'number' ? params.limit : undefined;
|
|
201
|
+
return normalizeTaskList(await sdk.listDlq(limit), 'tasks.listDlq');
|
|
202
|
+
},
|
|
203
|
+
cancel(taskId) {
|
|
204
|
+
if (!sdk.cancel) {
|
|
205
|
+
throw new Error('[svadmin/supabase] SupaCloud SDK client does not implement tasks.cancel');
|
|
206
|
+
}
|
|
207
|
+
return sdk.cancel(taskId);
|
|
208
|
+
},
|
|
209
|
+
retry(taskId) {
|
|
210
|
+
if (!sdk.retry) {
|
|
211
|
+
throw new Error('[svadmin/supabase] SupaCloud SDK client does not implement tasks.retry');
|
|
212
|
+
}
|
|
213
|
+
return sdk.retry(taskId);
|
|
214
|
+
},
|
|
215
|
+
subscribe(taskId, callback) {
|
|
216
|
+
if (!sdk.subscribe) {
|
|
217
|
+
throw new Error('[svadmin/supabase] SupaCloud SDK client does not implement tasks.subscribe');
|
|
218
|
+
}
|
|
219
|
+
return sdk.subscribe(taskId, {
|
|
220
|
+
onUpdate: callback,
|
|
221
|
+
});
|
|
222
|
+
},
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return supacloud as SupaCloudTaskLegacyClient<TTask>;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function getTaskSubscribeBridge<TTask extends SupaCloudTaskRecord>(
|
|
230
|
+
supacloud:
|
|
231
|
+
| Pick<SupaCloudTaskLegacyClient<TTask>, 'subscribe'>
|
|
232
|
+
| SupaCloudTaskSdkClient<TTask>,
|
|
233
|
+
): Pick<SupaCloudTaskLegacyClient<TTask>, 'subscribe'> {
|
|
234
|
+
if ('tasks' in supacloud && supacloud.tasks) {
|
|
235
|
+
return {
|
|
236
|
+
subscribe(taskId, callback) {
|
|
237
|
+
if (!supacloud.tasks.subscribe) {
|
|
238
|
+
throw new Error('[svadmin/supabase] SupaCloud SDK client does not implement tasks.subscribe');
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return supacloud.tasks.subscribe(taskId, {
|
|
242
|
+
onUpdate: callback,
|
|
243
|
+
});
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return supacloud as Pick<SupaCloudTaskLegacyClient<TTask>, 'subscribe'>;
|
|
62
249
|
}
|
|
63
250
|
|
|
64
251
|
function defaultMapTaskToEvent<TTask extends SupaCloudTaskRecord>(
|
|
@@ -75,7 +262,7 @@ function defaultMapTaskToEvent<TTask extends SupaCloudTaskRecord>(
|
|
|
75
262
|
export function createSupaCloudTaskProvider<
|
|
76
263
|
TTask extends SupaCloudTaskRecord = SupaCloudTaskRecord,
|
|
77
264
|
>(options: CreateSupaCloudTaskProviderOptions<TTask>): TaskProvider<TTask> {
|
|
78
|
-
const
|
|
265
|
+
const supacloud = getTaskBridge(options.supacloud);
|
|
79
266
|
|
|
80
267
|
return {
|
|
81
268
|
submit(taskName, submitOptions) {
|
|
@@ -88,13 +275,13 @@ export function createSupaCloudTaskProvider<
|
|
|
88
275
|
if (!supacloud.list) {
|
|
89
276
|
throw new Error('[svadmin/supabase] SupaCloud client does not implement tasks.list');
|
|
90
277
|
}
|
|
91
|
-
return normalizeTaskList(await supacloud.list(params));
|
|
278
|
+
return normalizeTaskList(await supacloud.list(params), 'tasks.list');
|
|
92
279
|
},
|
|
93
280
|
async listDlq(params) {
|
|
94
281
|
if (!supacloud.listDlq) {
|
|
95
282
|
throw new Error('[svadmin/supabase] SupaCloud client does not implement tasks.listDlq');
|
|
96
283
|
}
|
|
97
|
-
return normalizeTaskList(await supacloud.listDlq(params));
|
|
284
|
+
return normalizeTaskList(await supacloud.listDlq(params), 'tasks.listDlq');
|
|
98
285
|
},
|
|
99
286
|
cancel(taskId) {
|
|
100
287
|
if (!supacloud.cancel) {
|
|
@@ -120,12 +307,13 @@ export function createSupaCloudTaskProvider<
|
|
|
120
307
|
export function createSupaCloudTaskLiveProvider<
|
|
121
308
|
TTask extends SupaCloudTaskRecord = SupaCloudTaskRecord,
|
|
122
309
|
>(options: CreateSupaCloudTaskLiveProviderOptions<TTask>): LiveProvider {
|
|
310
|
+
const supacloud = getTaskSubscribeBridge(options.supacloud);
|
|
123
311
|
const resourceName = options.resource ?? 'tasks';
|
|
124
312
|
const mapTaskToEvent = options.mapTaskToEvent ?? defaultMapTaskToEvent<TTask>;
|
|
125
313
|
|
|
126
314
|
return {
|
|
127
315
|
subscribe({ resource, liveParams, callback }) {
|
|
128
|
-
if (!
|
|
316
|
+
if (!supacloud.subscribe) {
|
|
129
317
|
throw new Error('[svadmin/supabase] SupaCloud client does not implement tasks.subscribe');
|
|
130
318
|
}
|
|
131
319
|
|
|
@@ -134,7 +322,7 @@ export function createSupaCloudTaskLiveProvider<
|
|
|
134
322
|
throw new Error('[svadmin/supabase] createSupaCloudTaskLiveProvider requires liveParams.taskId');
|
|
135
323
|
}
|
|
136
324
|
|
|
137
|
-
const unsubscribe =
|
|
325
|
+
const unsubscribe = supacloud.subscribe(taskId, (task) => {
|
|
138
326
|
callback(mapTaskToEvent(task, resource || resourceName));
|
|
139
327
|
});
|
|
140
328
|
|