@btst/stack 2.11.0 → 2.11.2

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.
Files changed (71) hide show
  1. package/dist/packages/stack/src/plugins/blog/api/mutations.cjs +170 -0
  2. package/dist/packages/stack/src/plugins/blog/api/mutations.mjs +166 -0
  3. package/dist/packages/stack/src/plugins/blog/api/plugin.cjs +34 -157
  4. package/dist/packages/stack/src/plugins/blog/api/plugin.mjs +40 -163
  5. package/dist/packages/stack/src/plugins/media/api/plugin.cjs +4 -1
  6. package/dist/packages/stack/src/plugins/media/api/plugin.mjs +5 -2
  7. package/dist/plugins/blog/api/index.cjs +4 -0
  8. package/dist/plugins/blog/api/index.d.cts +2 -2
  9. package/dist/plugins/blog/api/index.d.mts +2 -2
  10. package/dist/plugins/blog/api/index.d.ts +2 -2
  11. package/dist/plugins/blog/api/index.mjs +1 -0
  12. package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
  13. package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
  14. package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
  15. package/dist/plugins/blog/client/index.d.cts +2 -2
  16. package/dist/plugins/blog/client/index.d.mts +2 -2
  17. package/dist/plugins/blog/client/index.d.ts +2 -2
  18. package/dist/plugins/blog/query-keys.d.cts +2 -2
  19. package/dist/plugins/blog/query-keys.d.mts +2 -2
  20. package/dist/plugins/blog/query-keys.d.ts +2 -2
  21. package/dist/plugins/kanban/api/index.d.cts +1 -1
  22. package/dist/plugins/kanban/api/index.d.mts +1 -1
  23. package/dist/plugins/kanban/api/index.d.ts +1 -1
  24. package/dist/plugins/kanban/query-keys.d.cts +1 -1
  25. package/dist/plugins/kanban/query-keys.d.mts +1 -1
  26. package/dist/plugins/kanban/query-keys.d.ts +1 -1
  27. package/dist/{packages/stack/src/plugins → plugins}/media/api/adapters/local.cjs +7 -1
  28. package/dist/plugins/media/api/adapters/local.d.cts +30 -0
  29. package/dist/plugins/media/api/adapters/local.d.mts +30 -0
  30. package/dist/plugins/media/api/adapters/local.d.ts +30 -0
  31. package/dist/{packages/stack/src/plugins → plugins}/media/api/adapters/local.mjs +7 -1
  32. package/dist/plugins/media/api/adapters/s3.d.cts +1 -1
  33. package/dist/plugins/media/api/adapters/s3.d.mts +1 -1
  34. package/dist/plugins/media/api/adapters/s3.d.ts +1 -1
  35. package/dist/plugins/media/api/adapters/vercel-blob.d.cts +1 -1
  36. package/dist/plugins/media/api/adapters/vercel-blob.d.mts +1 -1
  37. package/dist/plugins/media/api/adapters/vercel-blob.d.ts +1 -1
  38. package/dist/plugins/media/api/index.cjs +0 -2
  39. package/dist/plugins/media/api/index.d.cts +5 -102
  40. package/dist/plugins/media/api/index.d.mts +5 -102
  41. package/dist/plugins/media/api/index.d.ts +5 -102
  42. package/dist/plugins/media/api/index.mjs +0 -1
  43. package/dist/plugins/media/query-keys.d.cts +2 -2
  44. package/dist/plugins/media/query-keys.d.mts +2 -2
  45. package/dist/plugins/media/query-keys.d.ts +2 -2
  46. package/dist/shared/{stack.Bci0-plK.d.ts → stack.C5ucdatf.d.ts} +76 -3
  47. package/dist/shared/{stack.D7HSzZdG.d.ts → stack.D0p6oNme.d.ts} +90 -7
  48. package/dist/shared/{stack.6mEHS2WH.d.mts → stack.DOZ1EXjM.d.mts} +3 -3
  49. package/dist/shared/{stack.IUeyQKrm.d.mts → stack.DWipT53I.d.cts} +90 -7
  50. package/dist/shared/{stack.AJTXI7kw.d.cts → stack.DX-tQ93o.d.cts} +3 -3
  51. package/dist/shared/{stack.C_MUwwgR.d.mts → stack.DpZoZd98.d.mts} +76 -3
  52. package/dist/shared/{stack.DjgpFWq3.d.cts → stack.E17kSK1W.d.mts} +90 -7
  53. package/dist/shared/{stack.QYn-Px94.d.ts → stack.VF6FhyZw.d.ts} +3 -3
  54. package/dist/shared/{stack.DO6vOGQG.d.cts → stack.lkebw2nj.d.cts} +1 -1
  55. package/dist/shared/{stack.DO6vOGQG.d.mts → stack.lkebw2nj.d.mts} +1 -1
  56. package/dist/shared/{stack.DO6vOGQG.d.ts → stack.lkebw2nj.d.ts} +1 -1
  57. package/dist/shared/{stack.D6zyQnMo.d.cts → stack.vVFh38aS.d.cts} +76 -3
  58. package/package.json +14 -1
  59. package/src/plugins/blog/api/index.ts +7 -0
  60. package/src/plugins/blog/api/mutations.ts +287 -0
  61. package/src/plugins/blog/api/plugin.ts +43 -184
  62. package/src/plugins/media/__tests__/storage-adapters.test.ts +11 -0
  63. package/src/plugins/media/api/adapters/local.ts +10 -1
  64. package/src/plugins/media/api/index.ts +0 -5
  65. package/src/plugins/media/api/plugin.ts +6 -0
  66. package/dist/shared/{stack.eq5eg1yt.d.cts → stack.B6S3cgwN.d.cts} +6 -6
  67. package/dist/shared/{stack.BQmuNl5p.d.ts → stack.BWp0hcm9.d.cts} +3 -3
  68. package/dist/shared/{stack.BQmuNl5p.d.cts → stack.BWp0hcm9.d.mts} +3 -3
  69. package/dist/shared/{stack.BQmuNl5p.d.mts → stack.BWp0hcm9.d.ts} +3 -3
  70. package/dist/shared/{stack.Dj04W2c3.d.mts → stack.Bzfx-_lq.d.mts} +6 -6
  71. package/dist/shared/{stack.CMbX8Q5C.d.ts → stack.j5SFLC1d.d.ts} +6 -6
@@ -7,6 +7,13 @@ import type { Post, PostWithPostTag, Tag } from "../types";
7
7
  import { slugify } from "../utils";
8
8
  import { createPostSchema, updatePostSchema } from "../schemas";
9
9
  import { getAllPosts, getPostBySlug, getAllTags } from "./getters";
10
+ import {
11
+ createPost as createPostMutation,
12
+ updatePost as updatePostMutation,
13
+ deletePost as deletePostMutation,
14
+ type CreatePostInput,
15
+ type UpdatePostInput,
16
+ } from "./mutations";
10
17
  import { BLOG_QUERY_KEYS } from "./query-key-defs";
11
18
  import { serializePost, serializeTag } from "./serializers";
12
19
  import type { QueryClient } from "@tanstack/react-query";
@@ -260,85 +267,15 @@ export const blogBackendPlugin = (hooks?: BlogBackendHooks) =>
260
267
  getPostBySlug: (slug: string) => getPostBySlug(adapter, slug),
261
268
  getAllTags: () => getAllTags(adapter),
262
269
  prefetchForRoute: createBlogPrefetchForRoute(adapter),
270
+ // Mutations
271
+ createPost: (input: CreatePostInput) =>
272
+ createPostMutation(adapter, input),
273
+ updatePost: (id: string, input: UpdatePostInput) =>
274
+ updatePostMutation(adapter, id, input),
275
+ deletePost: (id: string) => deletePostMutation(adapter, id),
263
276
  }),
264
277
 
265
278
  routes: (adapter: Adapter) => {
266
- const findOrCreateTags = async (
267
- tagInputs: Array<
268
- { name: string } | { id: string; name: string; slug: string }
269
- >,
270
- ): Promise<Tag[]> => {
271
- if (tagInputs.length === 0) return [];
272
-
273
- const normalizeTagName = (name: string): string => {
274
- return name.trim();
275
- };
276
-
277
- const tagsWithIds: Tag[] = [];
278
- const tagsToFindOrCreate: Array<{ name: string }> = [];
279
-
280
- for (const tagInput of tagInputs) {
281
- if ("id" in tagInput && tagInput.id) {
282
- tagsWithIds.push({
283
- id: tagInput.id,
284
- name: normalizeTagName(tagInput.name),
285
- slug: tagInput.slug,
286
- createdAt: new Date(),
287
- updatedAt: new Date(),
288
- } as Tag);
289
- } else {
290
- tagsToFindOrCreate.push({ name: normalizeTagName(tagInput.name) });
291
- }
292
- }
293
-
294
- if (tagsToFindOrCreate.length === 0) {
295
- return tagsWithIds;
296
- }
297
-
298
- const allTags = await adapter.findMany<Tag>({
299
- model: "tag",
300
- });
301
- const tagMapBySlug = new Map<string, Tag>();
302
- for (const tag of allTags) {
303
- tagMapBySlug.set(tag.slug, tag);
304
- }
305
-
306
- const tagSlugs = tagsToFindOrCreate.map((tag) => slugify(tag.name));
307
- const foundTags: Tag[] = [];
308
-
309
- for (const slug of tagSlugs) {
310
- const tag = tagMapBySlug.get(slug);
311
- if (tag) {
312
- foundTags.push(tag);
313
- }
314
- }
315
-
316
- const existingSlugs = new Set([
317
- ...tagsWithIds.map((tag) => tag.slug),
318
- ...foundTags.map((tag) => tag.slug),
319
- ]);
320
- const tagsToCreate = tagsToFindOrCreate.filter(
321
- (tag) => !existingSlugs.has(slugify(tag.name)),
322
- );
323
-
324
- const createdTags: Tag[] = [];
325
- for (const tag of tagsToCreate) {
326
- const normalizedName = normalizeTagName(tag.name);
327
- const newTag = await adapter.create<Tag>({
328
- model: "tag",
329
- data: {
330
- name: normalizedName,
331
- slug: slugify(normalizedName),
332
- createdAt: new Date(),
333
- updatedAt: new Date(),
334
- },
335
- });
336
- createdTags.push(newTag);
337
- }
338
-
339
- return [...tagsWithIds, ...foundTags, ...createdTags];
340
- };
341
-
342
279
  const listPosts = createEndpoint(
343
280
  "/posts",
344
281
  {
@@ -394,11 +331,17 @@ export const blogBackendPlugin = (hooks?: BlogBackendHooks) =>
394
331
  );
395
332
  }
396
333
 
397
- const { tags, ...postData } = ctx.body;
398
- const tagNames = tags || [];
334
+ // Destructure and discard createdAt/updatedAt timestamps are always server-generated
335
+ const {
336
+ tags,
337
+ slug: rawSlug,
338
+ createdAt: _ca,
339
+ updatedAt: _ua,
340
+ ...postData
341
+ } = ctx.body;
399
342
 
400
343
  // Always slugify to ensure URL-safe slug, whether provided or generated from title
401
- const slug = slugify(postData.slug || postData.title);
344
+ const slug = slugify(rawSlug || postData.title);
402
345
 
403
346
  // Validate that slugification produced a non-empty result
404
347
  if (!slug) {
@@ -408,37 +351,14 @@ export const blogBackendPlugin = (hooks?: BlogBackendHooks) =>
408
351
  });
409
352
  }
410
353
 
411
- const newPost = await adapter.create<Post>({
412
- model: "post",
413
- data: {
414
- ...postData,
415
- slug,
416
- tags: [],
417
- createdAt: new Date(),
418
- updatedAt: new Date(),
419
- },
354
+ const newPost = await createPostMutation(adapter, {
355
+ ...postData,
356
+ slug,
357
+ tags: tags ?? [],
358
+ createdAt: new Date(),
359
+ updatedAt: new Date(),
420
360
  });
421
361
 
422
- if (tagNames.length > 0) {
423
- const createdTags = await findOrCreateTags(tagNames);
424
-
425
- await adapter.transaction(async (tx) => {
426
- for (const tag of createdTags) {
427
- await tx.create<{ postId: string; tagId: string }>({
428
- model: "postTag",
429
- data: {
430
- postId: newPost.id,
431
- tagId: tag.id,
432
- },
433
- });
434
- }
435
- });
436
-
437
- newPost.tags = createdTags.map((tag) => ({ ...tag }));
438
- } else {
439
- newPost.tags = [];
440
- }
441
-
442
362
  if (hooks?.onPostCreated) {
443
363
  await hooks.onPostCreated(newPost, context);
444
364
  }
@@ -475,8 +395,14 @@ export const blogBackendPlugin = (hooks?: BlogBackendHooks) =>
475
395
  );
476
396
  }
477
397
 
478
- const { tags, slug: rawSlug, ...restPostData } = ctx.body;
479
- const tagNames = tags || [];
398
+ // Destructure and discard createdAt/updatedAt timestamps are always server-generated
399
+ const {
400
+ tags,
401
+ slug: rawSlug,
402
+ createdAt: _ca,
403
+ updatedAt: _ua,
404
+ ...restPostData
405
+ } = ctx.body;
480
406
 
481
407
  // Sanitize slug if provided to ensure it's URL-safe
482
408
  const slugified = rawSlug ? slugify(rawSlug) : undefined;
@@ -489,80 +415,16 @@ export const blogBackendPlugin = (hooks?: BlogBackendHooks) =>
489
415
  });
490
416
  }
491
417
 
492
- const postData = {
418
+ const updated = await updatePostMutation(adapter, ctx.params.id, {
493
419
  ...restPostData,
494
420
  ...(slugified ? { slug: slugified } : {}),
495
- };
496
-
497
- const updated = await adapter.transaction(async (tx) => {
498
- const existingPostTags = await tx.findMany<{
499
- postId: string;
500
- tagId: string;
501
- }>({
502
- model: "postTag",
503
- where: [
504
- {
505
- field: "postId",
506
- value: ctx.params.id,
507
- operator: "eq" as const,
508
- },
509
- ],
510
- });
511
-
512
- const updatedPost = await tx.update<Post>({
513
- model: "post",
514
- where: [{ field: "id", value: ctx.params.id }],
515
- update: {
516
- ...postData,
517
- updatedAt: new Date(),
518
- },
519
- });
520
-
521
- if (!updatedPost) {
522
- throw ctx.error(404, {
523
- message: "Post not found",
524
- });
525
- }
526
-
527
- for (const postTag of existingPostTags) {
528
- await tx.delete<{ postId: string; tagId: string }>({
529
- model: "postTag",
530
- where: [
531
- {
532
- field: "postId",
533
- value: postTag.postId,
534
- operator: "eq" as const,
535
- },
536
- {
537
- field: "tagId",
538
- value: postTag.tagId,
539
- operator: "eq" as const,
540
- },
541
- ],
542
- });
543
- }
544
-
545
- if (tagNames.length > 0) {
546
- const createdTags = await findOrCreateTags(tagNames);
547
-
548
- for (const tag of createdTags) {
549
- await tx.create<{ postId: string; tagId: string }>({
550
- model: "postTag",
551
- data: {
552
- postId: ctx.params.id,
553
- tagId: tag.id,
554
- },
555
- });
556
- }
557
-
558
- updatedPost.tags = createdTags.map((tag) => ({ ...tag }));
559
- } else {
560
- updatedPost.tags = [];
561
- }
562
-
563
- return updatedPost;
421
+ tags: tags ?? [],
564
422
  });
565
423
 
424
+ if (!updated) {
425
+ throw ctx.error(404, { message: "Post not found" });
426
+ }
427
+
566
428
  if (hooks?.onPostUpdated) {
567
429
  await hooks.onPostUpdated(updated, context);
568
430
  }
@@ -597,10 +459,7 @@ export const blogBackendPlugin = (hooks?: BlogBackendHooks) =>
597
459
  );
598
460
  }
599
461
 
600
- await adapter.delete<Post>({
601
- model: "post",
602
- where: [{ field: "id", value: ctx.params.id }],
603
- });
462
+ await deletePostMutation(adapter, ctx.params.id);
604
463
 
605
464
  // Lifecycle hook
606
465
  if (hooks?.onPostDeleted) {
@@ -145,6 +145,17 @@ describe("localAdapter", () => {
145
145
  const adapter = localAdapter();
146
146
  expect(adapter.type).toBe("local");
147
147
  });
148
+
149
+ it("throws when a URL contains a path traversal sequence", async () => {
150
+ const uploadDir = await makeTmpDir();
151
+ const adapter = localAdapter({ uploadDir, publicPath: "/uploads" });
152
+
153
+ // Simulate a tampered URL that would resolve outside uploadDir after decoding.
154
+ const maliciousUrl = "/uploads/..%2F..%2Fetc%2Fpasswd";
155
+ await expect(adapter.delete(maliciousUrl)).rejects.toThrow(
156
+ "Refusing to delete file outside upload directory",
157
+ );
158
+ });
148
159
  });
149
160
 
150
161
  // ── S3 adapter ────────────────────────────────────────────────────────────────
@@ -66,7 +66,16 @@ export function localAdapter(
66
66
  if (!encodedFilename) return;
67
67
  const filename = decodeURIComponent(encodedFilename);
68
68
 
69
- const filePath = path.join(uploadDir, filename);
69
+ const resolvedUploadDir = path.resolve(uploadDir);
70
+ const filePath = path.join(resolvedUploadDir, filename);
71
+
72
+ // Guard against path traversal: reject any path that escapes uploadDir.
73
+ if (!filePath.startsWith(resolvedUploadDir + path.sep)) {
74
+ throw new Error(
75
+ `Refusing to delete file outside upload directory: ${filePath}`,
76
+ );
77
+ }
78
+
70
79
  try {
71
80
  await fs.unlink(filePath);
72
81
  } catch (err: unknown) {
@@ -26,11 +26,6 @@ export { serializeAsset, serializeFolder } from "./serializers";
26
26
 
27
27
  export { MEDIA_QUERY_KEYS, assetListDiscriminator } from "./query-key-defs";
28
28
 
29
- export {
30
- localAdapter,
31
- type LocalStorageAdapterOptions,
32
- } from "./adapters/local";
33
-
34
29
  export type {
35
30
  StorageAdapter,
36
31
  DirectStorageAdapter,
@@ -240,6 +240,10 @@ export const mediaBackendPlugin = (config: MediaBackendConfig) =>
240
240
  listAssets: (params?: Parameters<typeof listAssets>[1]) =>
241
241
  listAssets(adapter, params),
242
242
  getAssetById: (id: string) => getAssetById(adapter, id),
243
+ createAsset: (input: Parameters<typeof createAsset>[1]) =>
244
+ createAsset(adapter, input),
245
+ updateAsset: (id: string, input: Parameters<typeof updateAsset>[2]) =>
246
+ updateAsset(adapter, id, input),
243
247
  listFolders: (params?: Parameters<typeof listFolders>[1]) =>
244
248
  listFolders(adapter, params),
245
249
  getFolderById: (id: string) => getFolderById(adapter, id),
@@ -248,6 +252,8 @@ export const mediaBackendPlugin = (config: MediaBackendConfig) =>
248
252
  parentId?: string | null,
249
253
  tenantId?: string,
250
254
  ) => getFolderByName(adapter, name, parentId, tenantId),
255
+ createFolder: (input: Parameters<typeof createFolder>[1]) =>
256
+ createFolder(adapter, input),
251
257
  }),
252
258
 
253
259
  routes: (adapter: Adapter) => {
@@ -7,12 +7,12 @@ import { QueryClient } from '@tanstack/react-query';
7
7
 
8
8
  declare const createBoardSchema: z.ZodObject<{
9
9
  description: z.ZodOptional<z.ZodString>;
10
- name: z.ZodString;
11
10
  slug: z.ZodOptional<z.ZodString>;
12
11
  ownerId: z.ZodOptional<z.ZodString>;
13
12
  organizationId: z.ZodOptional<z.ZodString>;
14
13
  createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
15
14
  updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
15
+ name: z.ZodString;
16
16
  }, z.core.$strip>;
17
17
  declare const updateBoardSchema: z.ZodObject<{
18
18
  createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
@@ -26,10 +26,10 @@ declare const updateBoardSchema: z.ZodObject<{
26
26
  }, z.core.$strip>;
27
27
  declare const createColumnSchema: z.ZodObject<{
28
28
  title: z.ZodString;
29
- boardId: z.ZodString;
30
29
  createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
31
30
  updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
32
31
  order: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
32
+ boardId: z.ZodString;
33
33
  }, z.core.$strip>;
34
34
  declare const updateColumnSchema: z.ZodObject<{
35
35
  createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
@@ -360,20 +360,20 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
360
360
  method: "PUT";
361
361
  body: better_call.StandardSchemaV1<{
362
362
  description?: string | undefined;
363
- name?: string | undefined;
364
363
  slug?: string | undefined;
365
364
  ownerId?: string | undefined;
366
365
  organizationId?: string | undefined;
367
366
  createdAt?: unknown;
368
367
  updatedAt?: unknown;
368
+ name?: string | undefined;
369
369
  }, {
370
370
  description?: string | undefined;
371
- name?: string | undefined;
372
371
  slug?: string | undefined;
373
372
  ownerId?: string | undefined;
374
373
  organizationId?: string | undefined;
375
374
  createdAt?: unknown;
376
375
  updatedAt?: unknown;
376
+ name?: string | undefined;
377
377
  }>;
378
378
  }, Board>;
379
379
  readonly deleteBoard: better_call.StrictEndpoint<"/boards/:id", {} & {
@@ -402,16 +402,16 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
402
402
  method: "PUT";
403
403
  body: better_call.StandardSchemaV1<{
404
404
  title?: string | undefined;
405
- boardId?: string | undefined;
406
405
  createdAt?: unknown;
407
406
  updatedAt?: unknown;
408
407
  order?: number | undefined;
408
+ boardId?: string | undefined;
409
409
  }, {
410
410
  title?: string | undefined;
411
- boardId?: string | undefined;
412
411
  createdAt?: unknown;
413
412
  updatedAt?: unknown;
414
413
  order?: number | undefined;
414
+ boardId?: string | undefined;
415
415
  }>;
416
416
  }, Column>;
417
417
  readonly deleteColumn: better_call.StrictEndpoint<"/columns/:id", {} & {
@@ -42,15 +42,15 @@ declare const createPostSchema: z.ZodObject<{
42
42
  name: z.ZodString;
43
43
  slug: z.ZodString;
44
44
  }, z.core.$strip>]>>>>;
45
- title: z.ZodString;
46
45
  slug: z.ZodOptional<z.ZodString>;
46
+ published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
47
+ publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
47
48
  createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
48
49
  updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
49
- publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
50
+ title: z.ZodString;
50
51
  content: z.ZodString;
51
52
  excerpt: z.ZodString;
52
53
  image: z.ZodOptional<z.ZodString>;
53
- published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
54
54
  }, z.core.$strip>;
55
55
  declare const updatePostSchema: z.ZodObject<{
56
56
  publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
@@ -42,15 +42,15 @@ declare const createPostSchema: z.ZodObject<{
42
42
  name: z.ZodString;
43
43
  slug: z.ZodString;
44
44
  }, z.core.$strip>]>>>>;
45
- title: z.ZodString;
46
45
  slug: z.ZodOptional<z.ZodString>;
46
+ published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
47
+ publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
47
48
  createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
48
49
  updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
49
- publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
50
+ title: z.ZodString;
50
51
  content: z.ZodString;
51
52
  excerpt: z.ZodString;
52
53
  image: z.ZodOptional<z.ZodString>;
53
- published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
54
54
  }, z.core.$strip>;
55
55
  declare const updatePostSchema: z.ZodObject<{
56
56
  publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
@@ -42,15 +42,15 @@ declare const createPostSchema: z.ZodObject<{
42
42
  name: z.ZodString;
43
43
  slug: z.ZodString;
44
44
  }, z.core.$strip>]>>>>;
45
- title: z.ZodString;
46
45
  slug: z.ZodOptional<z.ZodString>;
46
+ published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
47
+ publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
47
48
  createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
48
49
  updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
49
- publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
50
+ title: z.ZodString;
50
51
  content: z.ZodString;
51
52
  excerpt: z.ZodString;
52
53
  image: z.ZodOptional<z.ZodString>;
53
- published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
54
54
  }, z.core.$strip>;
55
55
  declare const updatePostSchema: z.ZodObject<{
56
56
  publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
@@ -7,12 +7,12 @@ import { QueryClient } from '@tanstack/react-query';
7
7
 
8
8
  declare const createBoardSchema: z.ZodObject<{
9
9
  description: z.ZodOptional<z.ZodString>;
10
- name: z.ZodString;
11
10
  slug: z.ZodOptional<z.ZodString>;
12
11
  ownerId: z.ZodOptional<z.ZodString>;
13
12
  organizationId: z.ZodOptional<z.ZodString>;
14
13
  createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
15
14
  updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
15
+ name: z.ZodString;
16
16
  }, z.core.$strip>;
17
17
  declare const updateBoardSchema: z.ZodObject<{
18
18
  createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
@@ -26,10 +26,10 @@ declare const updateBoardSchema: z.ZodObject<{
26
26
  }, z.core.$strip>;
27
27
  declare const createColumnSchema: z.ZodObject<{
28
28
  title: z.ZodString;
29
- boardId: z.ZodString;
30
29
  createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
31
30
  updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
32
31
  order: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
32
+ boardId: z.ZodString;
33
33
  }, z.core.$strip>;
34
34
  declare const updateColumnSchema: z.ZodObject<{
35
35
  createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
@@ -360,20 +360,20 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
360
360
  method: "PUT";
361
361
  body: better_call.StandardSchemaV1<{
362
362
  description?: string | undefined;
363
- name?: string | undefined;
364
363
  slug?: string | undefined;
365
364
  ownerId?: string | undefined;
366
365
  organizationId?: string | undefined;
367
366
  createdAt?: unknown;
368
367
  updatedAt?: unknown;
368
+ name?: string | undefined;
369
369
  }, {
370
370
  description?: string | undefined;
371
- name?: string | undefined;
372
371
  slug?: string | undefined;
373
372
  ownerId?: string | undefined;
374
373
  organizationId?: string | undefined;
375
374
  createdAt?: unknown;
376
375
  updatedAt?: unknown;
376
+ name?: string | undefined;
377
377
  }>;
378
378
  }, Board>;
379
379
  readonly deleteBoard: better_call.StrictEndpoint<"/boards/:id", {} & {
@@ -402,16 +402,16 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
402
402
  method: "PUT";
403
403
  body: better_call.StandardSchemaV1<{
404
404
  title?: string | undefined;
405
- boardId?: string | undefined;
406
405
  createdAt?: unknown;
407
406
  updatedAt?: unknown;
408
407
  order?: number | undefined;
408
+ boardId?: string | undefined;
409
409
  }, {
410
410
  title?: string | undefined;
411
- boardId?: string | undefined;
412
411
  createdAt?: unknown;
413
412
  updatedAt?: unknown;
414
413
  order?: number | undefined;
414
+ boardId?: string | undefined;
415
415
  }>;
416
416
  }, Column>;
417
417
  readonly deleteColumn: better_call.StrictEndpoint<"/columns/:id", {} & {
@@ -7,12 +7,12 @@ import { QueryClient } from '@tanstack/react-query';
7
7
 
8
8
  declare const createBoardSchema: z.ZodObject<{
9
9
  description: z.ZodOptional<z.ZodString>;
10
- name: z.ZodString;
11
10
  slug: z.ZodOptional<z.ZodString>;
12
11
  ownerId: z.ZodOptional<z.ZodString>;
13
12
  organizationId: z.ZodOptional<z.ZodString>;
14
13
  createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
15
14
  updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
15
+ name: z.ZodString;
16
16
  }, z.core.$strip>;
17
17
  declare const updateBoardSchema: z.ZodObject<{
18
18
  createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
@@ -26,10 +26,10 @@ declare const updateBoardSchema: z.ZodObject<{
26
26
  }, z.core.$strip>;
27
27
  declare const createColumnSchema: z.ZodObject<{
28
28
  title: z.ZodString;
29
- boardId: z.ZodString;
30
29
  createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
31
30
  updatedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
32
31
  order: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
32
+ boardId: z.ZodString;
33
33
  }, z.core.$strip>;
34
34
  declare const updateColumnSchema: z.ZodObject<{
35
35
  createdAt: z.ZodOptional<z.ZodOptional<z.ZodCoercedDate<unknown>>>;
@@ -360,20 +360,20 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
360
360
  method: "PUT";
361
361
  body: better_call.StandardSchemaV1<{
362
362
  description?: string | undefined;
363
- name?: string | undefined;
364
363
  slug?: string | undefined;
365
364
  ownerId?: string | undefined;
366
365
  organizationId?: string | undefined;
367
366
  createdAt?: unknown;
368
367
  updatedAt?: unknown;
368
+ name?: string | undefined;
369
369
  }, {
370
370
  description?: string | undefined;
371
- name?: string | undefined;
372
371
  slug?: string | undefined;
373
372
  ownerId?: string | undefined;
374
373
  organizationId?: string | undefined;
375
374
  createdAt?: unknown;
376
375
  updatedAt?: unknown;
376
+ name?: string | undefined;
377
377
  }>;
378
378
  }, Board>;
379
379
  readonly deleteBoard: better_call.StrictEndpoint<"/boards/:id", {} & {
@@ -402,16 +402,16 @@ declare const kanbanBackendPlugin: (hooks?: KanbanBackendHooks) => _btst_stack_p
402
402
  method: "PUT";
403
403
  body: better_call.StandardSchemaV1<{
404
404
  title?: string | undefined;
405
- boardId?: string | undefined;
406
405
  createdAt?: unknown;
407
406
  updatedAt?: unknown;
408
407
  order?: number | undefined;
408
+ boardId?: string | undefined;
409
409
  }, {
410
410
  title?: string | undefined;
411
- boardId?: string | undefined;
412
411
  createdAt?: unknown;
413
412
  updatedAt?: unknown;
414
413
  order?: number | undefined;
414
+ boardId?: string | undefined;
415
415
  }>;
416
416
  }, Column>;
417
417
  readonly deleteColumn: better_call.StrictEndpoint<"/columns/:id", {} & {