includio-cms 0.7.2 → 0.13.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.
Files changed (164) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/ROADMAP.md +40 -2
  3. package/dist/admin/api/generate-styles.d.ts +2 -0
  4. package/dist/admin/api/generate-styles.js +32 -0
  5. package/dist/admin/api/handler.js +33 -0
  6. package/dist/admin/api/media-gc.js +10 -4
  7. package/dist/admin/api/rest/handler.js +17 -0
  8. package/dist/admin/api/rest/routes/collections.js +25 -13
  9. package/dist/admin/api/rest/routes/entries.d.ts +1 -1
  10. package/dist/admin/api/rest/routes/entries.js +10 -10
  11. package/dist/admin/api/rest/routes/media.d.ts +2 -0
  12. package/dist/admin/api/rest/routes/media.js +9 -0
  13. package/dist/admin/api/rest/routes/schema.d.ts +5 -0
  14. package/dist/admin/api/rest/routes/schema.js +152 -0
  15. package/dist/admin/api/rest/routes/singletons.d.ts +1 -1
  16. package/dist/admin/api/rest/routes/singletons.js +8 -7
  17. package/dist/admin/api/rest/routes/upload.d.ts +2 -0
  18. package/dist/admin/api/rest/routes/upload.js +28 -0
  19. package/dist/admin/api/upload.js +13 -0
  20. package/dist/admin/client/collection/collection-entries.svelte +19 -6
  21. package/dist/admin/client/entry/entry.svelte +21 -23
  22. package/dist/admin/client/entry/header/a11y-validator.js +2 -2
  23. package/dist/admin/client/entry/header/publish-panel.svelte +33 -85
  24. package/dist/admin/client/entry/header/status-badge.svelte +2 -2
  25. package/dist/admin/client/entry/header/version-history-sheet.svelte +9 -9
  26. package/dist/admin/client/entry/header/visibility.svelte +16 -10
  27. package/dist/admin/client/entry/utils.d.ts +3 -0
  28. package/dist/admin/client/entry/utils.js +22 -4
  29. package/dist/admin/client/form/form-submission/form-submission-page.svelte +4 -1
  30. package/dist/admin/client/form/form-submission/submission-field.svelte +10 -0
  31. package/dist/admin/client/index.d.ts +1 -0
  32. package/dist/admin/client/index.js +1 -0
  33. package/dist/admin/client/maintenance/maintenance-page.svelte +146 -2
  34. package/dist/admin/components/fields/blocks-field.svelte +9 -10
  35. package/dist/admin/components/fields/field-renderer.svelte +4 -8
  36. package/dist/admin/components/fields/object-field.svelte +7 -12
  37. package/dist/admin/components/fields/select-field.svelte +8 -2
  38. package/dist/admin/components/fields/seo-field.svelte +40 -93
  39. package/dist/admin/components/fields/simple-array-field.svelte +5 -5
  40. package/dist/admin/components/fields/text-field-wrapper.svelte +52 -197
  41. package/dist/admin/components/fields/text-field-wrapper.svelte.d.ts +2 -2
  42. package/dist/admin/components/fields/url-field-wrapper.svelte +15 -25
  43. package/dist/admin/components/fields/url-field.svelte +61 -72
  44. package/dist/admin/components/media/file-upload.svelte +5 -1
  45. package/dist/admin/components/media/file-upload.svelte.d.ts +1 -0
  46. package/dist/admin/components/media/media-library.svelte +109 -37
  47. package/dist/admin/components/media/media-selector.svelte +79 -11
  48. package/dist/admin/components/media/tag-sidebar.svelte +10 -6
  49. package/dist/admin/components/media/tag-sidebar.svelte.d.ts +7 -2
  50. package/dist/admin/components/tiptap/InlineBlockNodeView.svelte +21 -93
  51. package/dist/admin/components/tiptap/inline-block-node.js +6 -5
  52. package/dist/admin/components/tiptap/link-dialog.svelte +10 -11
  53. package/dist/admin/components/tiptap/slash-command.js +1 -1
  54. package/dist/admin/remote/entry.remote.d.ts +2 -5
  55. package/dist/admin/remote/entry.remote.js +22 -27
  56. package/dist/admin/remote/media.remote.d.ts +15 -0
  57. package/dist/admin/remote/media.remote.js +18 -2
  58. package/dist/admin/remote/preview.remote.js +3 -1
  59. package/dist/admin/utils/entryLabel.js +9 -6
  60. package/dist/admin/utils/translationStatus.js +1 -2
  61. package/dist/cli/scaffold/admin.js +34 -2
  62. package/dist/cms/runtime/api.d.ts +16 -12
  63. package/dist/cms/runtime/api.js +7 -6
  64. package/dist/cms/runtime/remote.js +2 -2
  65. package/dist/cms/runtime/schemas.d.ts +1 -1
  66. package/dist/cms/runtime/schemas.js +1 -1
  67. package/dist/cms/runtime/types.d.ts +118 -112
  68. package/dist/cms/runtime/types.js +0 -12
  69. package/dist/core/cms.d.ts +3 -1
  70. package/dist/core/cms.js +30 -0
  71. package/dist/core/fields/fieldSchemaToTs.js +9 -15
  72. package/dist/core/fields/formFieldSchemaToTs.js +7 -0
  73. package/dist/core/server/entries/operations/create.js +10 -4
  74. package/dist/core/server/entries/operations/get.d.ts +1 -0
  75. package/dist/core/server/entries/operations/get.js +186 -191
  76. package/dist/core/server/entries/operations/update.d.ts +6 -7
  77. package/dist/core/server/entries/operations/update.js +20 -38
  78. package/dist/core/server/fields/populateEntry.js +16 -52
  79. package/dist/core/server/fields/resolveImageFields.js +69 -120
  80. package/dist/core/server/fields/resolveRelationFields.js +30 -51
  81. package/dist/core/server/fields/resolveRichtextLinks.js +46 -100
  82. package/dist/core/server/fields/resolveTypographyOrphans.bench.d.ts +1 -0
  83. package/dist/core/server/fields/resolveTypographyOrphans.bench.js +87 -0
  84. package/dist/core/server/fields/resolveTypographyOrphans.d.ts +3 -0
  85. package/dist/core/server/fields/resolveTypographyOrphans.js +128 -0
  86. package/dist/core/server/fields/resolveUrlFields.js +47 -56
  87. package/dist/core/server/fields/utils/fixOrphans.d.ts +5 -0
  88. package/dist/core/server/fields/utils/fixOrphans.js +12 -0
  89. package/dist/core/server/fields/utils/imageStyles.d.ts +4 -2
  90. package/dist/core/server/fields/utils/imageStyles.js +41 -25
  91. package/dist/core/server/fields/utils/resolveMedia.js +1 -6
  92. package/dist/core/server/forms/submissions/operations/delete.js +26 -2
  93. package/dist/core/server/forms/submissions/utils/parseMultipart.d.ts +2 -0
  94. package/dist/core/server/forms/submissions/utils/parseMultipart.js +75 -0
  95. package/dist/core/server/generator/fields.d.ts +6 -0
  96. package/dist/core/server/generator/fields.js +43 -5
  97. package/dist/core/server/generator/formFieldSchemaToString.js +10 -0
  98. package/dist/core/server/generator/formFields.js +1 -0
  99. package/dist/core/server/generator/generator.js +98 -30
  100. package/dist/core/server/media/operations/getFiles.d.ts +5 -0
  101. package/dist/core/server/media/operations/getFiles.js +6 -0
  102. package/dist/core/server/media/operations/uploadPrivateFile.d.ts +4 -0
  103. package/dist/core/server/media/operations/uploadPrivateFile.js +8 -0
  104. package/dist/core/server/media/styles/operations/batchGenerateStyles.d.ts +16 -0
  105. package/dist/core/server/media/styles/operations/batchGenerateStyles.js +144 -0
  106. package/dist/db-postgres/index.js +303 -37
  107. package/dist/db-postgres/schema/entry.d.ts +0 -94
  108. package/dist/db-postgres/schema/entry.js +0 -6
  109. package/dist/db-postgres/schema/entryVersion.d.ts +17 -0
  110. package/dist/db-postgres/schema/entryVersion.js +1 -0
  111. package/dist/entity/index.d.ts +9 -4
  112. package/dist/entity/index.js +24 -24
  113. package/dist/files-local/index.js +43 -0
  114. package/dist/paraglide/messages/_index.d.ts +36 -3
  115. package/dist/paraglide/messages/_index.js +71 -3
  116. package/dist/paraglide/messages/en.d.ts +5 -0
  117. package/dist/paraglide/messages/en.js +14 -0
  118. package/dist/paraglide/messages/pl.d.ts +5 -0
  119. package/dist/paraglide/messages/pl.js +14 -0
  120. package/dist/sveltekit/components/preview.svelte +2 -326
  121. package/dist/sveltekit/components/preview.svelte.d.ts +5 -16
  122. package/dist/sveltekit/server/index.d.ts +2 -1
  123. package/dist/sveltekit/server/index.js +2 -1
  124. package/dist/sveltekit/server/preview.js +4 -7
  125. package/dist/types/adapters/db.d.ts +15 -1
  126. package/dist/types/adapters/files.d.ts +6 -0
  127. package/dist/types/cms.d.ts +5 -0
  128. package/dist/types/entries.d.ts +54 -18
  129. package/dist/types/fields.d.ts +14 -24
  130. package/dist/types/formFields.d.ts +7 -2
  131. package/dist/types/index.d.ts +2 -2
  132. package/dist/types/structured-content.d.ts +5 -0
  133. package/dist/updates/0.10.0/index.d.ts +2 -0
  134. package/dist/updates/0.10.0/index.js +15 -0
  135. package/dist/updates/0.11.0/index.d.ts +2 -0
  136. package/dist/updates/0.11.0/index.js +12 -0
  137. package/dist/updates/0.12.0/index.d.ts +2 -0
  138. package/dist/updates/0.12.0/index.js +12 -0
  139. package/dist/updates/0.13.0/index.d.ts +2 -0
  140. package/dist/updates/0.13.0/index.js +10 -0
  141. package/dist/updates/0.7.3/index.d.ts +2 -0
  142. package/dist/updates/0.7.3/index.js +10 -0
  143. package/dist/updates/0.8.0/index.d.ts +2 -0
  144. package/dist/updates/0.8.0/index.js +18 -0
  145. package/dist/updates/0.8.0/migrate.d.ts +2 -0
  146. package/dist/updates/0.8.0/migrate.js +101 -0
  147. package/dist/updates/0.9.0/index.d.ts +2 -0
  148. package/dist/updates/0.9.0/index.js +38 -0
  149. package/dist/updates/index.js +8 -1
  150. package/package.json +7 -6
  151. package/dist/admin/components/fields/image-field.svelte +0 -198
  152. package/dist/admin/components/fields/image-field.svelte.d.ts +0 -8
  153. package/dist/admin/components/fields/richtext-field.svelte +0 -13
  154. package/dist/admin/components/fields/richtext-field.svelte.d.ts +0 -8
  155. package/dist/admin/components/tiptap.svelte +0 -11
  156. package/dist/admin/components/tiptap.svelte.d.ts +0 -6
  157. package/dist/core/server/entries/utils/getEntryTranslation.d.ts +0 -1
  158. package/dist/core/server/entries/utils/getEntryTranslation.js +0 -18
  159. package/dist/paraglide/messages/hello_world.d.ts +0 -5
  160. package/dist/paraglide/messages/hello_world.js +0 -33
  161. package/dist/paraglide/messages/login_hello.d.ts +0 -16
  162. package/dist/paraglide/messages/login_hello.js +0 -34
  163. package/dist/paraglide/messages/login_please_login.d.ts +0 -16
  164. package/dist/paraglide/messages/login_please_login.js +0 -34
@@ -1,7 +1,7 @@
1
1
  // This file is auto-generated. Do not edit directly.
2
2
  import { command } from '$app/server';
3
3
  import { submitForm } from './api';
4
- import { contactFormSchema } from './schemas';
5
- export const submitContactCommand = command(contactFormSchema, async (data) => {
4
+ import { ContactFormSchema } from './schemas';
5
+ export const submitContactCommand = command(ContactFormSchema, async (data) => {
6
6
  await submitForm('contact', data);
7
7
  });
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- export declare const contactFormSchema: z.ZodObject<{
2
+ export declare const ContactFormSchema: z.ZodObject<{
3
3
  name: z.ZodString;
4
4
  email: z.ZodString;
5
5
  phone: z.ZodString;
@@ -1,6 +1,6 @@
1
1
  // This file is auto-generated. Do not edit directly.
2
2
  import { z } from 'zod';
3
- export const contactFormSchema = z.object({
3
+ export const ContactFormSchema = z.object({
4
4
  "name": z.string().min(1),
5
5
  "email": z.string().min(1).email(),
6
6
  "phone": z.string(),
@@ -1,135 +1,123 @@
1
- import type { ImageFieldData, StructuredContentDoc } from 'includio-cms/types';
1
+ import type { FlatImageFieldData, FlatVideoFieldData, StructuredContentDoc } from 'includio-cms/types';
2
2
  export type SingleSlug = "settings" | "image-showcase";
3
3
  export interface Settings {
4
- id: string;
5
- slug: string;
6
- data: {
7
- siteName: string;
8
- description?: string;
9
- logo?: ImageFieldData | null;
10
- favicon?: ImageFieldData | null;
11
- socialLinks?: ({
12
- slug: 'socialLink';
13
- data: {
14
- platform: string;
15
- url: {
16
- url: string;
17
- };
18
- };
19
- })[];
20
- footerText?: string;
21
- analyticsId?: string;
22
- customHeadCode?: string;
23
- };
24
- publishedAt: Date | null;
4
+ _id: string;
5
+ _slug: string;
6
+ _type: string;
7
+ _publishedAt: Date | null;
8
+ siteName: string;
9
+ description?: string;
10
+ logo?: FlatImageFieldData | FlatVideoFieldData | null;
11
+ favicon?: FlatImageFieldData | FlatVideoFieldData | null;
12
+ socialLinks?: ({
13
+ _slug: 'socialLink';
14
+ platform: string;
15
+ url: {
16
+ url: string;
17
+ };
18
+ })[];
19
+ footerText?: string;
20
+ analyticsId?: string;
21
+ customHeadCode?: string;
25
22
  }
26
23
  export interface ImageShowcase {
27
- id: string;
28
- slug: string;
29
- data: {
30
- photo?: ImageFieldData | null;
31
- };
32
- publishedAt: Date | null;
24
+ _id: string;
25
+ _slug: string;
26
+ _type: string;
27
+ _publishedAt: Date | null;
28
+ photo?: FlatImageFieldData | FlatVideoFieldData | null;
33
29
  }
34
30
  export type SingleEntryMap = {
35
31
  settings: Settings;
32
+ 'image-showcase': ImageShowcase;
36
33
  };
37
34
  export type CollectionSlug = "blog-post" | "project" | "array-test";
38
35
  export interface BlogPost {
39
- id: string;
40
- slug: string;
41
- data: {
36
+ _id: string;
37
+ _slug: string;
38
+ _type: string;
39
+ _publishedAt: Date | null;
40
+ title: string;
41
+ slug?: string;
42
+ cover?: FlatImageFieldData | FlatVideoFieldData | null;
43
+ rating: number;
44
+ category?: string;
45
+ publishedAt?: string;
46
+ thumbnail?: FlatImageFieldData | FlatVideoFieldData | null;
47
+ content?: StructuredContentDoc;
48
+ tags?: string[];
49
+ seo: {
50
+ slug: string;
51
+ canonicalUrl?: string;
42
52
  title: string;
43
- slug?: string;
44
- cover?: ImageFieldData | null;
45
- rating: number;
46
- category?: string;
47
- publishedAt?: string;
48
- thumbnail?: ImageFieldData | null;
49
- content?: StructuredContentDoc;
50
- tags?: string[];
51
- seo: {
52
- slug: string;
53
- canonicalUrl?: string;
54
- title: string;
55
- description?: string;
56
- ogImage?: string;
57
- keywords?: string;
58
- customCode?: string;
59
- };
60
- test?: ({
61
- slug: 'test-object';
62
- data: {
63
- dupa: string;
64
- };
65
- })[];
53
+ description?: string;
54
+ ogImage?: string;
55
+ keywords?: string;
56
+ customCode?: string;
66
57
  };
67
- publishedAt: Date | null;
58
+ test?: ({
59
+ _slug: 'test-object';
60
+ dupa: string;
61
+ })[];
68
62
  }
69
63
  export interface Project {
70
- id: string;
71
- slug: string;
72
- data: {
64
+ _id: string;
65
+ _slug: string;
66
+ _type: string;
67
+ _publishedAt: Date | null;
68
+ title: string;
69
+ description?: string;
70
+ status?: string;
71
+ startDate?: string;
72
+ url?: {
73
+ url: string;
74
+ };
75
+ image?: FlatImageFieldData | FlatVideoFieldData | null;
76
+ techStack?: ({
77
+ _slug: 'tech';
78
+ name: string;
79
+ })[];
80
+ seo: {
81
+ slug: string;
82
+ canonicalUrl?: string;
73
83
  title: string;
74
84
  description?: string;
75
- status?: string;
76
- startDate?: string;
77
- url?: {
78
- url: string;
79
- };
80
- image?: ImageFieldData | null;
81
- techStack?: ({
82
- slug: 'tech';
83
- data: {
84
- name: string;
85
- };
86
- })[];
87
- seo: {
88
- slug: string;
89
- canonicalUrl?: string;
90
- title: string;
91
- description?: string;
92
- ogImage?: string;
93
- keywords?: string;
94
- customCode?: string;
95
- };
85
+ ogImage?: string;
86
+ keywords?: string;
87
+ customCode?: string;
96
88
  };
97
- publishedAt: Date | null;
98
89
  }
99
90
  export interface ArrayTest {
100
- id: string;
101
- slug: string;
102
- data: {
103
- name: string;
104
- tags?: string[];
105
- localizedTags?: Record<string, string>[];
106
- scores?: number[];
107
- links?: UrlFieldData[];
108
- unlimited?: string[];
109
- content?: ({
110
- slug: 'text-block';
111
- data: {
112
- heading: string;
113
- body?: string;
114
- };
115
- } | {
116
- slug: 'image-block';
117
- data: {
118
- image: ImageFieldData;
119
- caption?: string;
120
- };
121
- })[];
122
- highlights?: ({
123
- slug: 'highlight';
124
- data: {
125
- title: string;
126
- value?: number;
127
- };
128
- })[];
129
- };
130
- publishedAt: Date | null;
91
+ _id: string;
92
+ _slug: string;
93
+ _type: string;
94
+ _publishedAt: Date | null;
95
+ name: string;
96
+ tags?: string[];
97
+ localizedTags?: Record<string, string>[];
98
+ scores?: number[];
99
+ links?: UrlFieldData[];
100
+ unlimited?: string[];
101
+ content?: ({
102
+ _slug: 'text-block';
103
+ heading: string;
104
+ body?: StructuredContentDoc;
105
+ } | {
106
+ _slug: 'image-block';
107
+ image: FlatImageFieldData | FlatVideoFieldData;
108
+ caption?: string;
109
+ })[];
110
+ highlights?: ({
111
+ _slug: 'highlight';
112
+ title: string;
113
+ value?: number;
114
+ })[];
131
115
  }
132
- export type CollectionEntryMap = {};
116
+ export type CollectionEntryMap = {
117
+ 'blog-post': BlogPost;
118
+ project: Project;
119
+ 'array-test': ArrayTest;
120
+ };
133
121
  export type FormSlug = "contact";
134
122
  export interface Contact {
135
123
  data: {
@@ -145,4 +133,22 @@ export interface Contact {
145
133
  export type FormEntryMap = {
146
134
  contact: Contact;
147
135
  };
136
+ export type CalloutBlockData = {
137
+ title?: string;
138
+ style?: string;
139
+ };
140
+ export type CtaBlockData = {
141
+ buttonText?: string;
142
+ url?: string;
143
+ variant?: string;
144
+ };
145
+ export type NoteBlockData = {
146
+ text?: string;
147
+ important?: boolean;
148
+ };
149
+ export type BlogPostContentBlockDataMap = {
150
+ callout: CalloutBlockData;
151
+ cta: CtaBlockData;
152
+ note: NoteBlockData;
153
+ };
148
154
  export type SiteLanguage = "en" | "pl";
@@ -1,15 +1,3 @@
1
1
  // This file is auto-generated. Do not edit directly.
2
2
  ;
3
- ;
4
- image - showcase;
5
- ImageShowcase;
6
- ;
7
- ;
8
- ;
9
- blog - post;
10
- BlogPost;
11
- project: Project;
12
- array - test;
13
- ArrayTest;
14
- ;
15
3
  export {};
@@ -1,6 +1,6 @@
1
1
  import type { DatabaseAdapter } from '../types/adapters/db.js';
2
2
  import type { FilesAdapter } from '../types/adapters/files.js';
3
- import type { ApiKeyConfig, AuthConfig, CMSConfig, ICMS, MediaConfig } from '../types/cms.js';
3
+ import type { ApiKeyConfig, AuthConfig, CMSConfig, ICMS, MediaConfig, TypographyConfig } from '../types/cms.js';
4
4
  import type { CollectionConfigWithType } from '../types/collections.js';
5
5
  import type { Language } from '../types/languages.js';
6
6
  import type { SingleConfigWithType } from '../types/singles.js';
@@ -22,10 +22,12 @@ export declare class CMS implements ICMS {
22
22
  forms: Record<string, FormConfig>;
23
23
  languages: Language[];
24
24
  mediaConfig: MediaConfig;
25
+ typographyConfig: TypographyConfig;
25
26
  plugins: PluginConfig[];
26
27
  customFields: Map<string, CustomFieldDefinition>;
27
28
  apiKeys: ApiKeyConfig[];
28
29
  constructor(config: CMSConfig);
30
+ private validateFieldSlugs;
29
31
  get auth(): ReturnType<typeof betterAuth>;
30
32
  getBySlug(slug: string): CollectionConfigWithType | SingleConfigWithType;
31
33
  getFormBySlug(slug: string): FormConfig;
package/dist/core/cms.js CHANGED
@@ -17,6 +17,7 @@ export class CMS {
17
17
  forms;
18
18
  languages;
19
19
  mediaConfig;
20
+ typographyConfig;
20
21
  plugins = [];
21
22
  customFields = new Map();
22
23
  apiKeys = [];
@@ -28,6 +29,7 @@ export class CMS {
28
29
  this.authConfig = config.auth ?? null;
29
30
  this.aiAdapter = config.ai || null;
30
31
  this.mediaConfig = config.media || {};
32
+ this.typographyConfig = config.typography || {};
31
33
  this.collections = {};
32
34
  this.singles = {};
33
35
  this.forms = {};
@@ -61,8 +63,36 @@ export class CMS {
61
63
  }
62
64
  }
63
65
  }
66
+ this.validateFieldSlugs();
64
67
  setSchemaGetCMS(() => this);
65
68
  }
69
+ validateFieldSlugs() {
70
+ const validateFields = (fields, context) => {
71
+ for (const field of fields) {
72
+ if (field.slug.startsWith('_')) {
73
+ throw new Error(`Field slug "${field.slug}" in ${context} cannot start with "_" (reserved for meta fields)`);
74
+ }
75
+ if (field.type === 'object' || field.type === 'blocks') {
76
+ const subFields = field.type === 'object' ? field.fields : field.of.flatMap((o) => o.fields);
77
+ validateFields(subFields, context);
78
+ }
79
+ if (field.type === 'content' && field.inlineBlocks) {
80
+ for (const block of field.inlineBlocks) {
81
+ if (block.slug.startsWith('_')) {
82
+ throw new Error(`Inline block slug "${block.slug}" in ${context} cannot start with "_" (reserved for meta fields)`);
83
+ }
84
+ validateFields(block.fields, `${context} > inline block "${block.slug}"`);
85
+ }
86
+ }
87
+ }
88
+ };
89
+ for (const col of Object.values(this.collections)) {
90
+ validateFields(col.fields, `collection "${col.slug}"`);
91
+ }
92
+ for (const single of Object.values(this.singles)) {
93
+ validateFields(single.fields, `single "${single.slug}"`);
94
+ }
95
+ }
66
96
  get auth() {
67
97
  if (!this._betterAuth) {
68
98
  if (!this.authConfig) {
@@ -42,14 +42,6 @@ export function generateZodSchemaFromField(field, languages, options = {
42
42
  return schema;
43
43
  return z.object(Object.fromEntries(languages.map((lang) => [lang, schema])));
44
44
  }
45
- case 'richtext': {
46
- let schema = z.string();
47
- if (field.required)
48
- schema = schema.min(1, { message: 'Pole wymagane' });
49
- if (!localized)
50
- return schema;
51
- return z.object(Object.fromEntries(languages.map((lang) => [lang, schema])));
52
- }
53
45
  case 'content': {
54
46
  const markSchema = z.object({
55
47
  type: z.string(),
@@ -140,7 +132,7 @@ export function generateZodSchemaFromField(field, languages, options = {
140
132
  case 'datetime':
141
133
  return z.string().datetime();
142
134
  case 'file':
143
- case 'image': {
135
+ case 'media': {
144
136
  const singleSchema = field.required
145
137
  ? z.string().uuid({ message: 'Pole wymagane' })
146
138
  : z.string();
@@ -150,7 +142,10 @@ export function generateZodSchemaFromField(field, languages, options = {
150
142
  case 'radio': {
151
143
  const enumValues = field.options.map((o) => o.value);
152
144
  const enumObject = z.enum(enumValues);
153
- return field.type === 'select' && field.multiple ? z.array(enumObject) : enumObject;
145
+ if (field.type === 'select' && field.multiple) {
146
+ return z.array(enumObject);
147
+ }
148
+ return field.required ? enumObject : enumObject.or(z.literal(''));
154
149
  }
155
150
  case 'checkboxes': {
156
151
  const checkValues = field.options.map((o) => JSON.stringify(o.value)).join(', ');
@@ -168,10 +163,9 @@ export function generateZodSchemaFromField(field, languages, options = {
168
163
  parentRequired: field.required,
169
164
  localized: options.localized
170
165
  });
171
- const finalData = !field.required ? data.partial().optional() : data;
172
- return z.object({
173
- slug: z.literal(field.slug),
174
- data: finalData
166
+ const base = !field.required ? data.partial() : data;
167
+ return base.extend({
168
+ _slug: z.literal(field.slug)
175
169
  });
176
170
  }
177
171
  case 'blocks': {
@@ -180,7 +174,7 @@ export function generateZodSchemaFromField(field, languages, options = {
180
174
  localized: options.localized
181
175
  }));
182
176
  const itemSchema = schemas.length > 1
183
- ? z.discriminatedUnion('slug', schemas)
177
+ ? z.discriminatedUnion('_slug', schemas)
184
178
  : schemas[0];
185
179
  let schema = z.array(itemSchema);
186
180
  if (field.minItems !== undefined &&
@@ -38,6 +38,13 @@ export function generateZodSchemaFromFormField(field) {
38
38
  const values = field.options.map((o) => o.value);
39
39
  return z.enum(values);
40
40
  }
41
+ case 'file': {
42
+ const base = z.string();
43
+ if (field.required) {
44
+ return base.min(1, errorMsg || undefined);
45
+ }
46
+ return base.optional().default('');
47
+ }
41
48
  default:
42
49
  return z.any();
43
50
  }
@@ -11,13 +11,16 @@ export const createEntrySchema = z.object({
11
11
  });
12
12
  export const createEntry = async (data) => {
13
13
  const { user } = requireAuth();
14
- const newDbEntry = await getCMS().databaseAdapter.createEntry({
14
+ const cms = getCMS();
15
+ const newDbEntry = await cms.databaseAdapter.createEntry({
15
16
  type: data.type,
16
17
  slug: data.slug
17
18
  });
18
- // Create an initial draft version for the new entry
19
- await getCMS().databaseAdapter.createEntryVersion({
19
+ // Create an initial draft version for default language only
20
+ const defaultLang = cms.languages[0];
21
+ await cms.databaseAdapter.createEntryVersion({
20
22
  entryId: newDbEntry.id,
23
+ lang: defaultLang,
21
24
  data: {},
22
25
  createdBy: user.id
23
26
  });
@@ -33,7 +36,10 @@ export const createEntryVersion = async (data, options) => {
33
36
  const entry = await getDbEntryOrThrow({ id: data.entryId });
34
37
  const config = getCMS().getBySlug(entry.slug);
35
38
  const languages = getCMS().languages;
36
- const schema = generateZodSchemaFromFields(getFieldsFromConfig(config), languages);
39
+ // Validate with localized: false — data is flat single-language
40
+ const schema = generateZodSchemaFromFields(getFieldsFromConfig(config), languages, {
41
+ localized: false
42
+ });
37
43
  const parsedData = schema.safeParse(data.data);
38
44
  if (!parsedData.success) {
39
45
  throw Error('Invalid data: ' + JSON.stringify(parsedData.error.flatten()));
@@ -8,6 +8,7 @@ export declare const getRawEntries: (options: GetRawEntriesOptions) => Promise<R
8
8
  export declare const getRawEntry: (options: getRawEntryOptions) => Promise<RawEntry | null>;
9
9
  export declare const getRawEntryOrThrow: (options: getRawEntryOptions) => Promise<RawEntry>;
10
10
  export declare const getEntries: (options?: GetEntriesOptions) => Promise<Entry[]>;
11
+ export declare const countEntries: (options: Omit<GetEntriesOptions, "limit" | "offset" | "orderBy">) => Promise<number>;
11
12
  export declare const getEntry: (options?: GetEntryOptions) => Promise<Entry | null>;
12
13
  export declare const getEntryOrThrow: (options?: GetEntryOptions) => Promise<Entry>;
13
14
  export declare const getEntryLabels: (options: {