@btst/stack 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/packages/stack/src/plugins/ai-chat/api/plugin.cjs +33 -47
- package/dist/packages/stack/src/plugins/ai-chat/api/plugin.mjs +33 -47
- package/dist/packages/stack/src/plugins/ai-chat/client/plugin.cjs +14 -21
- package/dist/packages/stack/src/plugins/ai-chat/client/plugin.mjs +15 -22
- package/dist/packages/stack/src/plugins/blog/api/plugin.cjs +28 -45
- package/dist/packages/stack/src/plugins/blog/api/plugin.mjs +22 -39
- package/dist/packages/stack/src/plugins/blog/client/plugin.cjs +23 -27
- package/dist/packages/stack/src/plugins/blog/client/plugin.mjs +24 -28
- package/dist/packages/stack/src/plugins/cms/api/plugin.cjs +14 -17
- package/dist/packages/stack/src/plugins/cms/api/plugin.mjs +14 -17
- package/dist/packages/stack/src/plugins/cms/client/plugin.cjs +11 -15
- package/dist/packages/stack/src/plugins/cms/client/plugin.mjs +12 -16
- package/dist/packages/stack/src/plugins/form-builder/api/plugin.cjs +58 -62
- package/dist/packages/stack/src/plugins/form-builder/api/plugin.mjs +58 -62
- package/dist/packages/stack/src/plugins/form-builder/client/plugin.cjs +12 -12
- package/dist/packages/stack/src/plugins/form-builder/client/plugin.mjs +13 -13
- package/dist/packages/stack/src/plugins/kanban/api/plugin.cjs +86 -117
- package/dist/packages/stack/src/plugins/kanban/api/plugin.mjs +83 -114
- package/dist/packages/stack/src/plugins/kanban/client/plugin.cjs +22 -29
- package/dist/packages/stack/src/plugins/kanban/client/plugin.mjs +23 -30
- package/dist/packages/stack/src/plugins/ui-builder/client/plugin.cjs +8 -8
- package/dist/packages/stack/src/plugins/ui-builder/client/plugin.mjs +9 -9
- package/dist/packages/stack/src/plugins/utils.cjs +42 -0
- package/dist/packages/stack/src/plugins/utils.mjs +41 -1
- package/dist/plugins/ai-chat/api/index.d.cts +1 -1
- package/dist/plugins/ai-chat/api/index.d.mts +1 -1
- package/dist/plugins/ai-chat/api/index.d.ts +1 -1
- package/dist/plugins/ai-chat/client/hooks/index.d.cts +1 -1
- package/dist/plugins/ai-chat/client/hooks/index.d.mts +1 -1
- package/dist/plugins/ai-chat/client/hooks/index.d.ts +1 -1
- package/dist/plugins/ai-chat/client/index.d.cts +8 -8
- package/dist/plugins/ai-chat/client/index.d.mts +8 -8
- package/dist/plugins/ai-chat/client/index.d.ts +8 -8
- package/dist/plugins/ai-chat/query-keys.d.cts +1 -1
- package/dist/plugins/ai-chat/query-keys.d.mts +1 -1
- package/dist/plugins/ai-chat/query-keys.d.ts +1 -1
- package/dist/plugins/blog/api/index.d.cts +1 -1
- package/dist/plugins/blog/api/index.d.mts +1 -1
- package/dist/plugins/blog/api/index.d.ts +1 -1
- package/dist/plugins/blog/client/index.d.cts +12 -12
- package/dist/plugins/blog/client/index.d.mts +12 -12
- package/dist/plugins/blog/client/index.d.ts +12 -12
- package/dist/plugins/blog/query-keys.d.cts +1 -1
- package/dist/plugins/blog/query-keys.d.mts +1 -1
- package/dist/plugins/blog/query-keys.d.ts +1 -1
- package/dist/plugins/client/index.cjs +1 -0
- package/dist/plugins/client/index.d.cts +8 -1
- package/dist/plugins/client/index.d.mts +8 -1
- package/dist/plugins/client/index.d.ts +8 -1
- package/dist/plugins/client/index.mjs +1 -1
- package/dist/plugins/cms/api/index.d.cts +2 -2
- package/dist/plugins/cms/api/index.d.mts +2 -2
- package/dist/plugins/cms/api/index.d.ts +2 -2
- package/dist/plugins/cms/client/hooks/index.d.cts +1 -1
- package/dist/plugins/cms/client/hooks/index.d.mts +1 -1
- package/dist/plugins/cms/client/hooks/index.d.ts +1 -1
- package/dist/plugins/cms/client/index.d.cts +6 -6
- package/dist/plugins/cms/client/index.d.mts +6 -6
- package/dist/plugins/cms/client/index.d.ts +6 -6
- package/dist/plugins/cms/query-keys.d.cts +2 -2
- package/dist/plugins/cms/query-keys.d.mts +2 -2
- package/dist/plugins/cms/query-keys.d.ts +2 -2
- package/dist/plugins/form-builder/api/index.d.cts +2 -2
- package/dist/plugins/form-builder/api/index.d.mts +2 -2
- package/dist/plugins/form-builder/api/index.d.ts +2 -2
- package/dist/plugins/form-builder/client/components/index.d.cts +1 -1
- package/dist/plugins/form-builder/client/components/index.d.mts +1 -1
- package/dist/plugins/form-builder/client/components/index.d.ts +1 -1
- package/dist/plugins/form-builder/client/hooks/index.d.cts +1 -1
- package/dist/plugins/form-builder/client/hooks/index.d.mts +1 -1
- package/dist/plugins/form-builder/client/hooks/index.d.ts +1 -1
- package/dist/plugins/form-builder/client/index.d.cts +6 -6
- package/dist/plugins/form-builder/client/index.d.mts +6 -6
- package/dist/plugins/form-builder/client/index.d.ts +6 -6
- package/dist/plugins/form-builder/query-keys.d.cts +2 -2
- package/dist/plugins/form-builder/query-keys.d.mts +2 -2
- package/dist/plugins/form-builder/query-keys.d.ts +2 -2
- package/dist/plugins/kanban/api/index.d.cts +1 -1
- package/dist/plugins/kanban/api/index.d.mts +1 -1
- package/dist/plugins/kanban/api/index.d.ts +1 -1
- package/dist/plugins/kanban/client/index.d.cts +12 -12
- package/dist/plugins/kanban/client/index.d.mts +12 -12
- package/dist/plugins/kanban/client/index.d.ts +12 -12
- package/dist/plugins/kanban/query-keys.d.cts +1 -1
- package/dist/plugins/kanban/query-keys.d.mts +1 -1
- package/dist/plugins/kanban/query-keys.d.ts +1 -1
- package/dist/plugins/ui-builder/client/hooks/index.d.cts +1 -1
- package/dist/plugins/ui-builder/client/hooks/index.d.mts +1 -1
- package/dist/plugins/ui-builder/client/hooks/index.d.ts +1 -1
- package/dist/plugins/ui-builder/client/index.d.cts +3 -3
- package/dist/plugins/ui-builder/client/index.d.mts +3 -3
- package/dist/plugins/ui-builder/client/index.d.ts +3 -3
- package/dist/plugins/ui-builder/index.d.cts +2 -2
- package/dist/plugins/ui-builder/index.d.mts +2 -2
- package/dist/plugins/ui-builder/index.d.ts +2 -2
- package/dist/shared/{stack.C-WUPMT6.d.cts → stack.B2xZTSiO.d.cts} +4 -4
- package/dist/shared/{stack.CczspVn2.d.mts → stack.B58oHdqm.d.mts} +1 -1
- package/dist/shared/{stack.CVDTkMoO.d.mts → stack.B8QD11QU.d.cts} +7 -7
- package/dist/shared/{stack.CVDTkMoO.d.cts → stack.B8QD11QU.d.mts} +7 -7
- package/dist/shared/{stack.CVDTkMoO.d.ts → stack.B8QD11QU.d.ts} +7 -7
- package/dist/shared/{stack.Kq2-QzOC.d.ts → stack.BDVEpue1.d.ts} +2 -2
- package/dist/shared/{stack.B7ONvlD_.d.mts → stack.BTvbxZvw.d.cts} +2 -2
- package/dist/shared/{stack.DdI5W6MB.d.mts → stack.BozPgbrZ.d.cts} +19 -19
- package/dist/shared/{stack.DdI5W6MB.d.cts → stack.BozPgbrZ.d.mts} +19 -19
- package/dist/shared/{stack.DdI5W6MB.d.ts → stack.BozPgbrZ.d.ts} +19 -19
- package/dist/shared/{stack.BUkC2EsZ.d.cts → stack.C9Mg2Q46.d.cts} +1 -1
- package/dist/shared/{stack.BEn34wW6.d.ts → stack.CTDVxbrA.d.ts} +12 -12
- package/dist/shared/{stack.C-Ptrz8s.d.ts → stack.Cj_zKww4.d.ts} +4 -4
- package/dist/shared/{stack.BepFXT3w.d.mts → stack.CxaFNQCV.d.mts} +25 -25
- package/dist/shared/{stack.DWoCZff7.d.cts → stack.D-b5zbPm.d.cts} +12 -12
- package/dist/shared/{stack.kcdnD4gA.d.cts → stack.DTtmJPQO.d.mts} +2 -2
- package/dist/shared/{stack.CL8ts1Mu.d.ts → stack.DXnclTG7.d.ts} +8 -8
- package/dist/shared/{stack.heOA9gzA.d.cts → stack.DaZM10cp.d.cts} +8 -8
- package/dist/shared/{stack.DTDxgFj8.d.mts → stack.FVWf2JhZ.d.mts} +12 -12
- package/dist/shared/{stack.Dk5r4W1F.d.mts → stack.cfCkioTe.d.mts} +8 -8
- package/dist/shared/{stack.6fUOjLs9.d.mts → stack.dH7u-TJH.d.mts} +4 -4
- package/dist/shared/{stack.CgWzG5jH.d.ts → stack.j75TpKh2.d.ts} +25 -25
- package/dist/shared/{stack.D3GB6wKv.d.cts → stack.n1_i1p2B.d.cts} +25 -25
- package/dist/shared/{stack.DASmUVjX.d.ts → stack.sO33ZDhK.d.ts} +1 -1
- package/package.json +1 -1
- package/src/plugins/ai-chat/api/plugin.ts +48 -63
- package/src/plugins/ai-chat/client/plugin.tsx +23 -31
- package/src/plugins/blog/api/plugin.ts +31 -47
- package/src/plugins/blog/client/plugin.tsx +36 -39
- package/src/plugins/client/index.ts +5 -1
- package/src/plugins/cms/api/plugin.ts +14 -17
- package/src/plugins/cms/client/plugin.tsx +18 -21
- package/src/plugins/cms/types.ts +7 -7
- package/src/plugins/form-builder/api/plugin.ts +64 -64
- package/src/plugins/form-builder/client/plugin.tsx +19 -18
- package/src/plugins/form-builder/types.ts +19 -24
- package/src/plugins/kanban/api/plugin.ts +111 -136
- package/src/plugins/kanban/client/plugin.tsx +35 -41
- package/src/plugins/ui-builder/client/plugin.tsx +11 -10
- package/src/plugins/ui-builder/types.ts +4 -4
- package/src/plugins/utils.ts +92 -1
|
@@ -5,6 +5,7 @@ import { BoardListQuerySchema, createBoardSchema, updateBoardSchema, createColum
|
|
|
5
5
|
import { getBoardById, getAllBoards } from './getters.mjs';
|
|
6
6
|
import { getKanbanColumnsByBoardId, findOrCreateKanbanBoard, createKanbanTask } from './mutations.mjs';
|
|
7
7
|
import { KANBAN_QUERY_KEYS } from './query-key-defs.mjs';
|
|
8
|
+
import { runHookWithShim } from '../../utils.mjs';
|
|
8
9
|
import { serializeBoard } from './serializers.mjs';
|
|
9
10
|
|
|
10
11
|
function createKanbanPrefetchForRoute(adapter) {
|
|
@@ -56,12 +57,11 @@ const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
56
57
|
const context = { query, headers };
|
|
57
58
|
try {
|
|
58
59
|
if (hooks?.onBeforeListBoards) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
60
|
+
await runHookWithShim(
|
|
61
|
+
() => hooks.onBeforeListBoards(query, context),
|
|
62
|
+
ctx.error,
|
|
63
|
+
"Unauthorized: Cannot list boards"
|
|
64
|
+
);
|
|
65
65
|
}
|
|
66
66
|
const result = await getAllBoards(adapter, query);
|
|
67
67
|
if (hooks?.onBoardsRead) {
|
|
@@ -86,12 +86,11 @@ const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
86
86
|
const context = { params, headers };
|
|
87
87
|
try {
|
|
88
88
|
if (hooks?.onBeforeReadBoard) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
89
|
+
await runHookWithShim(
|
|
90
|
+
() => hooks.onBeforeReadBoard(params.id, context),
|
|
91
|
+
ctx.error,
|
|
92
|
+
"Unauthorized: Cannot read board"
|
|
93
|
+
);
|
|
95
94
|
}
|
|
96
95
|
const result = await getBoardById(adapter, params.id);
|
|
97
96
|
if (!result) {
|
|
@@ -122,15 +121,11 @@ const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
122
121
|
};
|
|
123
122
|
try {
|
|
124
123
|
if (hooks?.onBeforeCreateBoard) {
|
|
125
|
-
|
|
126
|
-
ctx.body,
|
|
127
|
-
|
|
124
|
+
await runHookWithShim(
|
|
125
|
+
() => hooks.onBeforeCreateBoard(ctx.body, context),
|
|
126
|
+
ctx.error,
|
|
127
|
+
"Unauthorized: Cannot create board"
|
|
128
128
|
);
|
|
129
|
-
if (!canCreate) {
|
|
130
|
-
throw ctx.error(403, {
|
|
131
|
-
message: "Unauthorized: Cannot create board"
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
129
|
}
|
|
135
130
|
const { ...boardData } = ctx.body;
|
|
136
131
|
const slug = slugify(boardData.slug || boardData.name);
|
|
@@ -200,16 +195,15 @@ const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
200
195
|
};
|
|
201
196
|
try {
|
|
202
197
|
if (hooks?.onBeforeUpdateBoard) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
198
|
+
await runHookWithShim(
|
|
199
|
+
() => hooks.onBeforeUpdateBoard(
|
|
200
|
+
ctx.params.id,
|
|
201
|
+
{ ...ctx.body, id: ctx.params.id },
|
|
202
|
+
context
|
|
203
|
+
),
|
|
204
|
+
ctx.error,
|
|
205
|
+
"Unauthorized: Cannot update board"
|
|
207
206
|
);
|
|
208
|
-
if (!canUpdate) {
|
|
209
|
-
throw ctx.error(403, {
|
|
210
|
-
message: "Unauthorized: Cannot update board"
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
207
|
}
|
|
214
208
|
const { slug: rawSlug, ...restBoardData } = ctx.body;
|
|
215
209
|
const slugified = rawSlug ? slugify(rawSlug) : void 0;
|
|
@@ -266,15 +260,11 @@ const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
266
260
|
throw ctx.error(404, { message: "Board not found" });
|
|
267
261
|
}
|
|
268
262
|
if (hooks?.onBeforeDeleteBoard) {
|
|
269
|
-
|
|
270
|
-
ctx.params.id,
|
|
271
|
-
|
|
263
|
+
await runHookWithShim(
|
|
264
|
+
() => hooks.onBeforeDeleteBoard(ctx.params.id, context),
|
|
265
|
+
ctx.error,
|
|
266
|
+
"Unauthorized: Cannot delete board"
|
|
272
267
|
);
|
|
273
|
-
if (!canDelete) {
|
|
274
|
-
throw ctx.error(403, {
|
|
275
|
-
message: "Unauthorized: Cannot delete board"
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
268
|
}
|
|
279
269
|
await adapter.delete({
|
|
280
270
|
model: "kanbanBoard",
|
|
@@ -305,15 +295,11 @@ const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
305
295
|
};
|
|
306
296
|
try {
|
|
307
297
|
if (hooks?.onBeforeCreateColumn) {
|
|
308
|
-
|
|
309
|
-
ctx.body,
|
|
310
|
-
|
|
298
|
+
await runHookWithShim(
|
|
299
|
+
() => hooks.onBeforeCreateColumn(ctx.body, context),
|
|
300
|
+
ctx.error,
|
|
301
|
+
"Unauthorized: Cannot create column"
|
|
311
302
|
);
|
|
312
|
-
if (!canCreate) {
|
|
313
|
-
throw ctx.error(403, {
|
|
314
|
-
message: "Unauthorized: Cannot create column"
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
303
|
}
|
|
318
304
|
const existingColumns = await adapter.findMany({
|
|
319
305
|
model: "kanbanColumn",
|
|
@@ -358,16 +344,15 @@ const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
358
344
|
};
|
|
359
345
|
try {
|
|
360
346
|
if (hooks?.onBeforeUpdateColumn) {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
347
|
+
await runHookWithShim(
|
|
348
|
+
() => hooks.onBeforeUpdateColumn(
|
|
349
|
+
ctx.params.id,
|
|
350
|
+
{ ...ctx.body, id: ctx.params.id },
|
|
351
|
+
context
|
|
352
|
+
),
|
|
353
|
+
ctx.error,
|
|
354
|
+
"Unauthorized: Cannot update column"
|
|
365
355
|
);
|
|
366
|
-
if (!canUpdate) {
|
|
367
|
-
throw ctx.error(403, {
|
|
368
|
-
message: "Unauthorized: Cannot update column"
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
356
|
}
|
|
372
357
|
const updated = await adapter.update({
|
|
373
358
|
model: "kanbanColumn",
|
|
@@ -410,15 +395,11 @@ const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
410
395
|
throw ctx.error(404, { message: "Column not found" });
|
|
411
396
|
}
|
|
412
397
|
if (hooks?.onBeforeDeleteColumn) {
|
|
413
|
-
|
|
414
|
-
ctx.params.id,
|
|
415
|
-
|
|
398
|
+
await runHookWithShim(
|
|
399
|
+
() => hooks.onBeforeDeleteColumn(ctx.params.id, context),
|
|
400
|
+
ctx.error,
|
|
401
|
+
"Unauthorized: Cannot delete column"
|
|
416
402
|
);
|
|
417
|
-
if (!canDelete) {
|
|
418
|
-
throw ctx.error(403, {
|
|
419
|
-
message: "Unauthorized: Cannot delete column"
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
403
|
}
|
|
423
404
|
await adapter.delete({
|
|
424
405
|
model: "kanbanColumn",
|
|
@@ -449,16 +430,15 @@ const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
449
430
|
for (let i = 0; i < columnIds.length; i++) {
|
|
450
431
|
const columnId = columnIds[i];
|
|
451
432
|
if (!columnId) continue;
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
433
|
+
await runHookWithShim(
|
|
434
|
+
() => hooks.onBeforeUpdateColumn(
|
|
435
|
+
columnId,
|
|
436
|
+
{ id: columnId, order: i },
|
|
437
|
+
context
|
|
438
|
+
),
|
|
439
|
+
ctx.error,
|
|
440
|
+
"Unauthorized: Cannot reorder columns"
|
|
456
441
|
);
|
|
457
|
-
if (!canUpdate) {
|
|
458
|
-
throw ctx.error(403, {
|
|
459
|
-
message: "Unauthorized: Cannot reorder columns"
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
442
|
}
|
|
463
443
|
}
|
|
464
444
|
const updatedColumns = [];
|
|
@@ -500,15 +480,11 @@ const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
500
480
|
};
|
|
501
481
|
try {
|
|
502
482
|
if (hooks?.onBeforeCreateTask) {
|
|
503
|
-
|
|
504
|
-
ctx.body,
|
|
505
|
-
|
|
483
|
+
await runHookWithShim(
|
|
484
|
+
() => hooks.onBeforeCreateTask(ctx.body, context),
|
|
485
|
+
ctx.error,
|
|
486
|
+
"Unauthorized: Cannot create task"
|
|
506
487
|
);
|
|
507
|
-
if (!canCreate) {
|
|
508
|
-
throw ctx.error(403, {
|
|
509
|
-
message: "Unauthorized: Cannot create task"
|
|
510
|
-
});
|
|
511
|
-
}
|
|
512
488
|
}
|
|
513
489
|
const existingTasks = await adapter.findMany({
|
|
514
490
|
model: "kanbanTask",
|
|
@@ -559,16 +535,15 @@ const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
559
535
|
};
|
|
560
536
|
try {
|
|
561
537
|
if (hooks?.onBeforeUpdateTask) {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
538
|
+
await runHookWithShim(
|
|
539
|
+
() => hooks.onBeforeUpdateTask(
|
|
540
|
+
ctx.params.id,
|
|
541
|
+
{ ...ctx.body, id: ctx.params.id },
|
|
542
|
+
context
|
|
543
|
+
),
|
|
544
|
+
ctx.error,
|
|
545
|
+
"Unauthorized: Cannot update task"
|
|
566
546
|
);
|
|
567
|
-
if (!canUpdate) {
|
|
568
|
-
throw ctx.error(403, {
|
|
569
|
-
message: "Unauthorized: Cannot update task"
|
|
570
|
-
});
|
|
571
|
-
}
|
|
572
547
|
}
|
|
573
548
|
const updated = await adapter.update({
|
|
574
549
|
model: "kanbanTask",
|
|
@@ -611,15 +586,11 @@ const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
611
586
|
throw ctx.error(404, { message: "Task not found" });
|
|
612
587
|
}
|
|
613
588
|
if (hooks?.onBeforeDeleteTask) {
|
|
614
|
-
|
|
615
|
-
ctx.params.id,
|
|
616
|
-
|
|
589
|
+
await runHookWithShim(
|
|
590
|
+
() => hooks.onBeforeDeleteTask(ctx.params.id, context),
|
|
591
|
+
ctx.error,
|
|
592
|
+
"Unauthorized: Cannot delete task"
|
|
617
593
|
);
|
|
618
|
-
if (!canDelete) {
|
|
619
|
-
throw ctx.error(403, {
|
|
620
|
-
message: "Unauthorized: Cannot delete task"
|
|
621
|
-
});
|
|
622
|
-
}
|
|
623
594
|
}
|
|
624
595
|
await adapter.delete({
|
|
625
596
|
model: "kanbanTask",
|
|
@@ -654,16 +625,15 @@ const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
654
625
|
throw ctx.error(404, { message: "Task not found" });
|
|
655
626
|
}
|
|
656
627
|
if (hooks?.onBeforeUpdateTask) {
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
628
|
+
await runHookWithShim(
|
|
629
|
+
() => hooks.onBeforeUpdateTask(
|
|
630
|
+
taskId,
|
|
631
|
+
{ id: taskId, columnId: targetColumnId, order: targetOrder },
|
|
632
|
+
context
|
|
633
|
+
),
|
|
634
|
+
ctx.error,
|
|
635
|
+
"Unauthorized: Cannot move task"
|
|
661
636
|
);
|
|
662
|
-
if (!canUpdate) {
|
|
663
|
-
throw ctx.error(403, {
|
|
664
|
-
message: "Unauthorized: Cannot move task"
|
|
665
|
-
});
|
|
666
|
-
}
|
|
667
637
|
}
|
|
668
638
|
const updated = await adapter.update({
|
|
669
639
|
model: "kanbanTask",
|
|
@@ -699,16 +669,15 @@ const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
699
669
|
for (let i = 0; i < taskIds.length; i++) {
|
|
700
670
|
const taskId = taskIds[i];
|
|
701
671
|
if (!taskId) continue;
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
672
|
+
await runHookWithShim(
|
|
673
|
+
() => hooks.onBeforeUpdateTask(
|
|
674
|
+
taskId,
|
|
675
|
+
{ id: taskId, order: i },
|
|
676
|
+
context
|
|
677
|
+
),
|
|
678
|
+
ctx.error,
|
|
679
|
+
"Unauthorized: Cannot reorder tasks"
|
|
706
680
|
);
|
|
707
|
-
if (!canUpdate) {
|
|
708
|
-
throw ctx.error(403, {
|
|
709
|
-
message: "Unauthorized: Cannot reorder tasks"
|
|
710
|
-
});
|
|
711
|
-
}
|
|
712
681
|
}
|
|
713
682
|
}
|
|
714
683
|
const updatedTasks = [];
|
|
@@ -21,10 +21,10 @@ function createBoardsLoader(config) {
|
|
|
21
21
|
};
|
|
22
22
|
try {
|
|
23
23
|
if (hooks?.beforeLoadBoards) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
await client.runClientHookWithShim(
|
|
25
|
+
() => hooks.beforeLoadBoards(context),
|
|
26
|
+
"Load prevented by beforeLoadBoards hook"
|
|
27
|
+
);
|
|
28
28
|
}
|
|
29
29
|
const client$1 = client.createApiClient({
|
|
30
30
|
baseURL: apiBaseURL,
|
|
@@ -37,13 +37,10 @@ function createBoardsLoader(config) {
|
|
|
37
37
|
const boards = queryClient.getQueryData(
|
|
38
38
|
listQuery.queryKey
|
|
39
39
|
);
|
|
40
|
-
|
|
41
|
-
boards || null,
|
|
42
|
-
|
|
40
|
+
await client.runClientHookWithShim(
|
|
41
|
+
() => hooks.afterLoadBoards(boards || null, context),
|
|
42
|
+
"Load prevented by afterLoadBoards hook"
|
|
43
43
|
);
|
|
44
|
-
if (canContinue === false) {
|
|
45
|
-
throw new Error("Load prevented by afterLoadBoards hook");
|
|
46
|
-
}
|
|
47
44
|
}
|
|
48
45
|
const queryState = queryClient.getQueryState(listQuery.queryKey);
|
|
49
46
|
if (queryState?.error && hooks?.onLoadError) {
|
|
@@ -77,10 +74,10 @@ function createBoardLoader(boardId, config) {
|
|
|
77
74
|
};
|
|
78
75
|
try {
|
|
79
76
|
if (hooks?.beforeLoadBoard) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
await client.runClientHookWithShim(
|
|
78
|
+
() => hooks.beforeLoadBoard(boardId, context),
|
|
79
|
+
"Load prevented by beforeLoadBoard hook"
|
|
80
|
+
);
|
|
84
81
|
}
|
|
85
82
|
const client$1 = client.createApiClient({
|
|
86
83
|
baseURL: apiBaseURL,
|
|
@@ -93,14 +90,10 @@ function createBoardLoader(boardId, config) {
|
|
|
93
90
|
const board = queryClient.getQueryData(
|
|
94
91
|
boardQuery.queryKey
|
|
95
92
|
);
|
|
96
|
-
|
|
97
|
-
board || null,
|
|
98
|
-
|
|
99
|
-
context
|
|
93
|
+
await client.runClientHookWithShim(
|
|
94
|
+
() => hooks.afterLoadBoard(board || null, boardId, context),
|
|
95
|
+
"Load prevented by afterLoadBoard hook"
|
|
100
96
|
);
|
|
101
|
-
if (canContinue === false) {
|
|
102
|
-
throw new Error("Load prevented by afterLoadBoard hook");
|
|
103
|
-
}
|
|
104
97
|
}
|
|
105
98
|
const queryState = queryClient.getQueryState(boardQuery.queryKey);
|
|
106
99
|
if (queryState?.error && hooks?.onLoadError) {
|
|
@@ -133,16 +126,16 @@ function createNewBoardLoader(config) {
|
|
|
133
126
|
};
|
|
134
127
|
try {
|
|
135
128
|
if (hooks?.beforeLoadNewBoard) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
129
|
+
await client.runClientHookWithShim(
|
|
130
|
+
() => hooks.beforeLoadNewBoard(context),
|
|
131
|
+
"Load prevented by beforeLoadNewBoard hook"
|
|
132
|
+
);
|
|
140
133
|
}
|
|
141
134
|
if (hooks?.afterLoadNewBoard) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
135
|
+
await client.runClientHookWithShim(
|
|
136
|
+
() => hooks.afterLoadNewBoard(context),
|
|
137
|
+
"Load prevented by afterLoadNewBoard hook"
|
|
138
|
+
);
|
|
146
139
|
}
|
|
147
140
|
} catch (error) {
|
|
148
141
|
if (hooks?.onLoadError) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { defineClientPlugin, createApiClient, isConnectionError } from '@btst/stack/plugins/client';
|
|
2
|
+
import { defineClientPlugin, createApiClient, runClientHookWithShim, isConnectionError } from '@btst/stack/plugins/client';
|
|
3
3
|
import { createRoute } from '@btst/yar';
|
|
4
4
|
import { createKanbanQueryKeys } from '../../../../../../plugins/kanban/query-keys.mjs';
|
|
5
5
|
import { BoardsListPageComponent } from './components/pages/boards-list-page.mjs';
|
|
@@ -19,10 +19,10 @@ function createBoardsLoader(config) {
|
|
|
19
19
|
};
|
|
20
20
|
try {
|
|
21
21
|
if (hooks?.beforeLoadBoards) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
await runClientHookWithShim(
|
|
23
|
+
() => hooks.beforeLoadBoards(context),
|
|
24
|
+
"Load prevented by beforeLoadBoards hook"
|
|
25
|
+
);
|
|
26
26
|
}
|
|
27
27
|
const client = createApiClient({
|
|
28
28
|
baseURL: apiBaseURL,
|
|
@@ -35,13 +35,10 @@ function createBoardsLoader(config) {
|
|
|
35
35
|
const boards = queryClient.getQueryData(
|
|
36
36
|
listQuery.queryKey
|
|
37
37
|
);
|
|
38
|
-
|
|
39
|
-
boards || null,
|
|
40
|
-
|
|
38
|
+
await runClientHookWithShim(
|
|
39
|
+
() => hooks.afterLoadBoards(boards || null, context),
|
|
40
|
+
"Load prevented by afterLoadBoards hook"
|
|
41
41
|
);
|
|
42
|
-
if (canContinue === false) {
|
|
43
|
-
throw new Error("Load prevented by afterLoadBoards hook");
|
|
44
|
-
}
|
|
45
42
|
}
|
|
46
43
|
const queryState = queryClient.getQueryState(listQuery.queryKey);
|
|
47
44
|
if (queryState?.error && hooks?.onLoadError) {
|
|
@@ -75,10 +72,10 @@ function createBoardLoader(boardId, config) {
|
|
|
75
72
|
};
|
|
76
73
|
try {
|
|
77
74
|
if (hooks?.beforeLoadBoard) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
75
|
+
await runClientHookWithShim(
|
|
76
|
+
() => hooks.beforeLoadBoard(boardId, context),
|
|
77
|
+
"Load prevented by beforeLoadBoard hook"
|
|
78
|
+
);
|
|
82
79
|
}
|
|
83
80
|
const client = createApiClient({
|
|
84
81
|
baseURL: apiBaseURL,
|
|
@@ -91,14 +88,10 @@ function createBoardLoader(boardId, config) {
|
|
|
91
88
|
const board = queryClient.getQueryData(
|
|
92
89
|
boardQuery.queryKey
|
|
93
90
|
);
|
|
94
|
-
|
|
95
|
-
board || null,
|
|
96
|
-
|
|
97
|
-
context
|
|
91
|
+
await runClientHookWithShim(
|
|
92
|
+
() => hooks.afterLoadBoard(board || null, boardId, context),
|
|
93
|
+
"Load prevented by afterLoadBoard hook"
|
|
98
94
|
);
|
|
99
|
-
if (canContinue === false) {
|
|
100
|
-
throw new Error("Load prevented by afterLoadBoard hook");
|
|
101
|
-
}
|
|
102
95
|
}
|
|
103
96
|
const queryState = queryClient.getQueryState(boardQuery.queryKey);
|
|
104
97
|
if (queryState?.error && hooks?.onLoadError) {
|
|
@@ -131,16 +124,16 @@ function createNewBoardLoader(config) {
|
|
|
131
124
|
};
|
|
132
125
|
try {
|
|
133
126
|
if (hooks?.beforeLoadNewBoard) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
127
|
+
await runClientHookWithShim(
|
|
128
|
+
() => hooks.beforeLoadNewBoard(context),
|
|
129
|
+
"Load prevented by beforeLoadNewBoard hook"
|
|
130
|
+
);
|
|
138
131
|
}
|
|
139
132
|
if (hooks?.afterLoadNewBoard) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
133
|
+
await runClientHookWithShim(
|
|
134
|
+
() => hooks.afterLoadNewBoard(context),
|
|
135
|
+
"Load prevented by afterLoadNewBoard hook"
|
|
136
|
+
);
|
|
144
137
|
}
|
|
145
138
|
} catch (error) {
|
|
146
139
|
if (hooks?.onLoadError) {
|
|
@@ -31,10 +31,10 @@ function createPageListLoader(config) {
|
|
|
31
31
|
};
|
|
32
32
|
try {
|
|
33
33
|
if (hooks?.beforeLoadPageList) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
await client.runClientHookWithShim(
|
|
35
|
+
() => hooks.beforeLoadPageList(context),
|
|
36
|
+
"Load prevented by beforeLoadPageList hook"
|
|
37
|
+
);
|
|
38
38
|
}
|
|
39
39
|
const client$1 = client.createApiClient({
|
|
40
40
|
baseURL: apiBaseURL,
|
|
@@ -97,10 +97,10 @@ function createPageBuilderLoader(id, config) {
|
|
|
97
97
|
};
|
|
98
98
|
try {
|
|
99
99
|
if (hooks?.beforeLoadPageBuilder) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
await client.runClientHookWithShim(
|
|
101
|
+
() => hooks.beforeLoadPageBuilder(id, context),
|
|
102
|
+
"Load prevented by beforeLoadPageBuilder hook"
|
|
103
|
+
);
|
|
104
104
|
}
|
|
105
105
|
const client$1 = client.createApiClient({
|
|
106
106
|
baseURL: apiBaseURL,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { lazy } from 'react';
|
|
3
|
-
import { defineClientPlugin, createApiClient } from '@btst/stack/plugins/client';
|
|
3
|
+
import { defineClientPlugin, createApiClient, runClientHookWithShim } from '@btst/stack/plugins/client';
|
|
4
4
|
import { createRoute } from '@btst/yar';
|
|
5
5
|
import { createCMSQueryKeys } from '../../../../../../plugins/cms/query-keys.mjs';
|
|
6
6
|
import { UI_BUILDER_TYPE_SLUG } from '../schemas.mjs';
|
|
@@ -29,10 +29,10 @@ function createPageListLoader(config) {
|
|
|
29
29
|
};
|
|
30
30
|
try {
|
|
31
31
|
if (hooks?.beforeLoadPageList) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
await runClientHookWithShim(
|
|
33
|
+
() => hooks.beforeLoadPageList(context),
|
|
34
|
+
"Load prevented by beforeLoadPageList hook"
|
|
35
|
+
);
|
|
36
36
|
}
|
|
37
37
|
const client = createApiClient({
|
|
38
38
|
baseURL: apiBaseURL,
|
|
@@ -95,10 +95,10 @@ function createPageBuilderLoader(id, config) {
|
|
|
95
95
|
};
|
|
96
96
|
try {
|
|
97
97
|
if (hooks?.beforeLoadPageBuilder) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
await runClientHookWithShim(
|
|
99
|
+
() => hooks.beforeLoadPageBuilder(id, context),
|
|
100
|
+
"Load prevented by beforeLoadPageBuilder hook"
|
|
101
|
+
);
|
|
102
102
|
}
|
|
103
103
|
const client = createApiClient({
|
|
104
104
|
baseURL: apiBaseURL,
|
|
@@ -2,6 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
const client = require('better-call/client');
|
|
4
4
|
|
|
5
|
+
async function runHookWithShim(hookFn, createError, defaultMessage, errorStatus = 403) {
|
|
6
|
+
let result;
|
|
7
|
+
try {
|
|
8
|
+
result = await hookFn();
|
|
9
|
+
} catch (e) {
|
|
10
|
+
throw createError(errorStatus, {
|
|
11
|
+
message: e instanceof Error ? e.message : defaultMessage
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
if (typeof result === "boolean") {
|
|
15
|
+
if (process.env.NODE_ENV !== "production") {
|
|
16
|
+
console.warn(
|
|
17
|
+
`[btst] A lifecycle hook returned a boolean (${result}). Boolean returns are deprecated \u2014 throw an Error to deny access instead. IMPORTANT: any code path in this hook that falls through to undefined now ALLOWS access (previously denied). Update the hook to throw new Error("Unauthorized") to deny.`
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
if (!result) {
|
|
21
|
+
throw createError(errorStatus, { message: defaultMessage });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
async function runClientHookWithShim(hookFn, defaultMessage) {
|
|
27
|
+
let result;
|
|
28
|
+
try {
|
|
29
|
+
result = await hookFn();
|
|
30
|
+
} catch (e) {
|
|
31
|
+
throw e instanceof Error ? e : new Error(defaultMessage);
|
|
32
|
+
}
|
|
33
|
+
if (typeof result === "boolean") {
|
|
34
|
+
if (process.env.NODE_ENV !== "production") {
|
|
35
|
+
console.warn(
|
|
36
|
+
`[btst] A lifecycle hook returned a boolean (${result}). Boolean returns are deprecated \u2014 throw an Error to deny access instead. IMPORTANT: any code path in this hook that falls through to undefined now ALLOWS access (previously denied). Update the hook to throw new Error("Unauthorized") to deny.`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
if (!result) {
|
|
40
|
+
throw new Error(defaultMessage);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
5
45
|
function isConnectionError(err) {
|
|
6
46
|
if (!(err instanceof Error)) return false;
|
|
7
47
|
const code = err.cause?.code ?? err.code;
|
|
@@ -20,3 +60,5 @@ function createApiClient(options) {
|
|
|
20
60
|
|
|
21
61
|
exports.createApiClient = createApiClient;
|
|
22
62
|
exports.isConnectionError = isConnectionError;
|
|
63
|
+
exports.runClientHookWithShim = runClientHookWithShim;
|
|
64
|
+
exports.runHookWithShim = runHookWithShim;
|
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
import { createClient } from 'better-call/client';
|
|
2
2
|
|
|
3
|
+
async function runHookWithShim(hookFn, createError, defaultMessage, errorStatus = 403) {
|
|
4
|
+
let result;
|
|
5
|
+
try {
|
|
6
|
+
result = await hookFn();
|
|
7
|
+
} catch (e) {
|
|
8
|
+
throw createError(errorStatus, {
|
|
9
|
+
message: e instanceof Error ? e.message : defaultMessage
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
if (typeof result === "boolean") {
|
|
13
|
+
if (process.env.NODE_ENV !== "production") {
|
|
14
|
+
console.warn(
|
|
15
|
+
`[btst] A lifecycle hook returned a boolean (${result}). Boolean returns are deprecated \u2014 throw an Error to deny access instead. IMPORTANT: any code path in this hook that falls through to undefined now ALLOWS access (previously denied). Update the hook to throw new Error("Unauthorized") to deny.`
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
if (!result) {
|
|
19
|
+
throw createError(errorStatus, { message: defaultMessage });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
async function runClientHookWithShim(hookFn, defaultMessage) {
|
|
25
|
+
let result;
|
|
26
|
+
try {
|
|
27
|
+
result = await hookFn();
|
|
28
|
+
} catch (e) {
|
|
29
|
+
throw e instanceof Error ? e : new Error(defaultMessage);
|
|
30
|
+
}
|
|
31
|
+
if (typeof result === "boolean") {
|
|
32
|
+
if (process.env.NODE_ENV !== "production") {
|
|
33
|
+
console.warn(
|
|
34
|
+
`[btst] A lifecycle hook returned a boolean (${result}). Boolean returns are deprecated \u2014 throw an Error to deny access instead. IMPORTANT: any code path in this hook that falls through to undefined now ALLOWS access (previously denied). Update the hook to throw new Error("Unauthorized") to deny.`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
if (!result) {
|
|
38
|
+
throw new Error(defaultMessage);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
3
43
|
function isConnectionError(err) {
|
|
4
44
|
if (!(err instanceof Error)) return false;
|
|
5
45
|
const code = err.cause?.code ?? err.code;
|
|
@@ -16,4 +56,4 @@ function createApiClient(options) {
|
|
|
16
56
|
});
|
|
17
57
|
}
|
|
18
58
|
|
|
19
|
-
export { createApiClient, isConnectionError };
|
|
59
|
+
export { createApiClient, isConnectionError, runClientHookWithShim, runHookWithShim };
|