@velora-cms/api-schemas 0.9.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 (59) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +22 -0
  3. package/dist/api-error.schema.d.ts +5 -0
  4. package/dist/api-error.schema.js +6 -0
  5. package/dist/api-key-api.schema.d.ts +50 -0
  6. package/dist/api-key-api.schema.js +29 -0
  7. package/dist/auth.schema.d.ts +40 -0
  8. package/dist/auth.schema.js +30 -0
  9. package/dist/content-api.schema.d.ts +188 -0
  10. package/dist/content-api.schema.js +121 -0
  11. package/dist/content-trash-api.schema.d.ts +20 -0
  12. package/dist/content-trash-api.schema.js +23 -0
  13. package/dist/content-trash.schema.d.ts +31 -0
  14. package/dist/content-trash.schema.js +26 -0
  15. package/dist/content-version.schema.d.ts +11 -0
  16. package/dist/content-version.schema.js +10 -0
  17. package/dist/content.schema.d.ts +15 -0
  18. package/dist/content.schema.js +14 -0
  19. package/dist/data-type-api.schema.d.ts +36 -0
  20. package/dist/data-type-api.schema.js +32 -0
  21. package/dist/data-type-config.schema.d.ts +9 -0
  22. package/dist/data-type-config.schema.js +32 -0
  23. package/dist/document-type-api.schema.d.ts +202 -0
  24. package/dist/document-type-api.schema.js +86 -0
  25. package/dist/document-type.schema.d.ts +90 -0
  26. package/dist/document-type.schema.js +103 -0
  27. package/dist/health.schema.d.ts +6 -0
  28. package/dist/health.schema.js +5 -0
  29. package/dist/index.d.ts +54 -0
  30. package/dist/index.js +27 -0
  31. package/dist/marketplace-listing-api.schema.d.ts +205 -0
  32. package/dist/marketplace-listing-api.schema.js +115 -0
  33. package/dist/media-api.schema.d.ts +36 -0
  34. package/dist/media-api.schema.js +23 -0
  35. package/dist/media.schema.d.ts +11 -0
  36. package/dist/media.schema.js +10 -0
  37. package/dist/plugin-management-api.schema.d.ts +145 -0
  38. package/dist/plugin-management-api.schema.js +186 -0
  39. package/dist/plugin-registry-api.schema.d.ts +31 -0
  40. package/dist/plugin-registry-api.schema.js +25 -0
  41. package/dist/plugin-storage-api.schema.d.ts +15 -0
  42. package/dist/plugin-storage-api.schema.js +24 -0
  43. package/dist/public-api.schema.d.ts +211 -0
  44. package/dist/public-api.schema.js +185 -0
  45. package/dist/setup-api.schema.d.ts +78 -0
  46. package/dist/setup-api.schema.js +88 -0
  47. package/dist/snapshot-api.schema.d.ts +43 -0
  48. package/dist/snapshot-api.schema.js +25 -0
  49. package/dist/snapshot.schema.d.ts +28 -0
  50. package/dist/snapshot.schema.js +17 -0
  51. package/dist/template-api.schema.d.ts +33 -0
  52. package/dist/template-api.schema.js +28 -0
  53. package/dist/template.schema.d.ts +7 -0
  54. package/dist/template.schema.js +13 -0
  55. package/dist/theme-api.schema.d.ts +21 -0
  56. package/dist/theme-api.schema.js +14 -0
  57. package/dist/user-api.schema.d.ts +79 -0
  58. package/dist/user-api.schema.js +36 -0
  59. package/package.json +26 -0
@@ -0,0 +1,211 @@
1
+ import { z } from "zod";
2
+ export declare const PublicContentExtensionsSchema: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>;
3
+ export declare const PublicContentItemSchema: z.ZodObject<{
4
+ id: z.ZodString;
5
+ documentTypeId: z.ZodString;
6
+ locale: z.ZodString;
7
+ publishedAt: z.ZodNullable<z.ZodString>;
8
+ version: z.ZodNumber;
9
+ data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
10
+ extensions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
11
+ }, z.core.$strip>;
12
+ export type PublicContentItem = z.infer<typeof PublicContentItemSchema>;
13
+ export declare const PublicContentItemQuerySchema: z.ZodObject<{
14
+ locale: z.ZodOptional<z.ZodString>;
15
+ fallback: z.ZodOptional<z.ZodString>;
16
+ format: z.ZodOptional<z.ZodString>;
17
+ previewToken: z.ZodOptional<z.ZodString>;
18
+ }, z.core.$strip>;
19
+ export type PublicContentItemQuery = z.infer<typeof PublicContentItemQuerySchema>;
20
+ export declare const PublicContentFormatResponseSchema: z.ZodObject<{
21
+ format: z.ZodString;
22
+ content: z.ZodUnknown;
23
+ }, z.core.$strip>;
24
+ export type PublicContentFormatResponse = z.infer<typeof PublicContentFormatResponseSchema>;
25
+ export declare const PublicContentByPathQuerySchema: z.ZodObject<{
26
+ locale: z.ZodOptional<z.ZodString>;
27
+ fallback: z.ZodOptional<z.ZodString>;
28
+ format: z.ZodOptional<z.ZodString>;
29
+ previewToken: z.ZodOptional<z.ZodString>;
30
+ path: z.ZodString;
31
+ }, z.core.$strip>;
32
+ export type PublicContentByPathQuery = z.infer<typeof PublicContentByPathQuerySchema>;
33
+ export declare const PublicContentListQuerySchema: z.ZodObject<{
34
+ cursor: z.ZodOptional<z.ZodString>;
35
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
36
+ }, z.core.$strip>;
37
+ export type PublicContentListQuery = z.infer<typeof PublicContentListQuerySchema>;
38
+ export declare const PublicContentNodeSummarySchema: z.ZodObject<{
39
+ id: z.ZodString;
40
+ parentId: z.ZodNullable<z.ZodString>;
41
+ path: z.ZodString;
42
+ depth: z.ZodNumber;
43
+ sortOrder: z.ZodNumber;
44
+ documentTypeId: z.ZodString;
45
+ locale: z.ZodString;
46
+ publishedAt: z.ZodString;
47
+ }, z.core.$strip>;
48
+ export type PublicContentNodeSummary = z.infer<typeof PublicContentNodeSummarySchema>;
49
+ export declare const PublicContentListResponseSchema: z.ZodObject<{
50
+ items: z.ZodArray<z.ZodObject<{
51
+ id: z.ZodString;
52
+ parentId: z.ZodNullable<z.ZodString>;
53
+ path: z.ZodString;
54
+ depth: z.ZodNumber;
55
+ sortOrder: z.ZodNumber;
56
+ documentTypeId: z.ZodString;
57
+ locale: z.ZodString;
58
+ publishedAt: z.ZodString;
59
+ }, z.core.$strip>>;
60
+ nextCursor: z.ZodNullable<z.ZodString>;
61
+ }, z.core.$strip>;
62
+ export type PublicContentListResponse = z.infer<typeof PublicContentListResponseSchema>;
63
+ export declare const PublicContentSearchQuerySchema: z.ZodObject<{
64
+ documentTypeId: z.ZodOptional<z.ZodString>;
65
+ under: z.ZodOptional<z.ZodString>;
66
+ q: z.ZodOptional<z.ZodString>;
67
+ cursor: z.ZodOptional<z.ZodString>;
68
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
69
+ }, z.core.$strip>;
70
+ export type PublicContentSearchQuery = z.infer<typeof PublicContentSearchQuerySchema>;
71
+ export declare const PublicMediaFileSchema: z.ZodObject<{
72
+ id: z.ZodString;
73
+ filename: z.ZodString;
74
+ mimeType: z.ZodString;
75
+ size: z.ZodNumber;
76
+ downloadUrl: z.ZodString;
77
+ uploadedAt: z.ZodString;
78
+ }, z.core.$strip>;
79
+ export type PublicMediaFile = z.infer<typeof PublicMediaFileSchema>;
80
+ export declare const PublicMediaListQuerySchema: z.ZodObject<{
81
+ cursor: z.ZodOptional<z.ZodString>;
82
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
83
+ search: z.ZodOptional<z.ZodString>;
84
+ }, z.core.$strip>;
85
+ export type PublicMediaListQuery = z.infer<typeof PublicMediaListQuerySchema>;
86
+ export declare const PublicMediaListResponseSchema: z.ZodObject<{
87
+ items: z.ZodArray<z.ZodObject<{
88
+ id: z.ZodString;
89
+ filename: z.ZodString;
90
+ mimeType: z.ZodString;
91
+ size: z.ZodNumber;
92
+ downloadUrl: z.ZodString;
93
+ uploadedAt: z.ZodString;
94
+ }, z.core.$strip>>;
95
+ nextCursor: z.ZodNullable<z.ZodString>;
96
+ }, z.core.$strip>;
97
+ export type PublicMediaListResponse = z.infer<typeof PublicMediaListResponseSchema>;
98
+ export declare const PublicFieldDefinitionSchema: z.ZodObject<{
99
+ id: z.ZodString;
100
+ name: z.ZodString;
101
+ datatypeId: z.ZodString;
102
+ validation: z.ZodOptional<z.ZodObject<{
103
+ required: z.ZodOptional<z.ZodBoolean>;
104
+ minLength: z.ZodOptional<z.ZodNumber>;
105
+ maxLength: z.ZodOptional<z.ZodNumber>;
106
+ min: z.ZodOptional<z.ZodNumber>;
107
+ max: z.ZodOptional<z.ZodNumber>;
108
+ pattern: z.ZodOptional<z.ZodString>;
109
+ }, z.core.$strip>>;
110
+ }, z.core.$strip>;
111
+ export type PublicFieldDefinition = z.infer<typeof PublicFieldDefinitionSchema>;
112
+ export declare const PublicDocumentTypeSchema: z.ZodObject<{
113
+ id: z.ZodString;
114
+ name: z.ZodString;
115
+ icon: z.ZodString;
116
+ kind: z.ZodEnum<{
117
+ page: "page";
118
+ element: "element";
119
+ }>;
120
+ fields: z.ZodArray<z.ZodObject<{
121
+ id: z.ZodString;
122
+ name: z.ZodString;
123
+ datatypeId: z.ZodString;
124
+ validation: z.ZodOptional<z.ZodObject<{
125
+ required: z.ZodOptional<z.ZodBoolean>;
126
+ minLength: z.ZodOptional<z.ZodNumber>;
127
+ maxLength: z.ZodOptional<z.ZodNumber>;
128
+ min: z.ZodOptional<z.ZodNumber>;
129
+ max: z.ZodOptional<z.ZodNumber>;
130
+ pattern: z.ZodOptional<z.ZodString>;
131
+ }, z.core.$strip>>;
132
+ }, z.core.$strip>>;
133
+ }, z.core.$strip>;
134
+ export type PublicDocumentType = z.infer<typeof PublicDocumentTypeSchema>;
135
+ export declare const PublicDocumentTypeListQuerySchema: z.ZodObject<{
136
+ cursor: z.ZodOptional<z.ZodString>;
137
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
138
+ }, z.core.$strip>;
139
+ export type PublicDocumentTypeListQuery = z.infer<typeof PublicDocumentTypeListQuerySchema>;
140
+ export declare const PublicDocumentTypeListResponseSchema: z.ZodObject<{
141
+ items: z.ZodArray<z.ZodObject<{
142
+ id: z.ZodString;
143
+ name: z.ZodString;
144
+ icon: z.ZodString;
145
+ kind: z.ZodEnum<{
146
+ page: "page";
147
+ element: "element";
148
+ }>;
149
+ fields: z.ZodArray<z.ZodObject<{
150
+ id: z.ZodString;
151
+ name: z.ZodString;
152
+ datatypeId: z.ZodString;
153
+ validation: z.ZodOptional<z.ZodObject<{
154
+ required: z.ZodOptional<z.ZodBoolean>;
155
+ minLength: z.ZodOptional<z.ZodNumber>;
156
+ maxLength: z.ZodOptional<z.ZodNumber>;
157
+ min: z.ZodOptional<z.ZodNumber>;
158
+ max: z.ZodOptional<z.ZodNumber>;
159
+ pattern: z.ZodOptional<z.ZodString>;
160
+ }, z.core.$strip>>;
161
+ }, z.core.$strip>>;
162
+ }, z.core.$strip>>;
163
+ nextCursor: z.ZodNullable<z.ZodString>;
164
+ }, z.core.$strip>;
165
+ export type PublicDocumentTypeListResponse = z.infer<typeof PublicDocumentTypeListResponseSchema>;
166
+ export declare const PublicTemplateSchema: z.ZodObject<{
167
+ id: z.ZodString;
168
+ name: z.ZodString;
169
+ documentTypeId: z.ZodString;
170
+ }, z.core.$strip>;
171
+ export type PublicTemplate = z.infer<typeof PublicTemplateSchema>;
172
+ export declare const PublicTemplateListQuerySchema: z.ZodObject<{
173
+ cursor: z.ZodOptional<z.ZodString>;
174
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
175
+ documentTypeId: z.ZodOptional<z.ZodString>;
176
+ }, z.core.$strip>;
177
+ export type PublicTemplateListQuery = z.infer<typeof PublicTemplateListQuerySchema>;
178
+ export declare const PublicTemplateListResponseSchema: z.ZodObject<{
179
+ items: z.ZodArray<z.ZodObject<{
180
+ id: z.ZodString;
181
+ name: z.ZodString;
182
+ documentTypeId: z.ZodString;
183
+ }, z.core.$strip>>;
184
+ nextCursor: z.ZodNullable<z.ZodString>;
185
+ }, z.core.$strip>;
186
+ export type PublicTemplateListResponse = z.infer<typeof PublicTemplateListResponseSchema>;
187
+ export declare const PublicContentWriteResponseSchema: z.ZodObject<{
188
+ id: z.ZodString;
189
+ documentTypeId: z.ZodString;
190
+ parentId: z.ZodNullable<z.ZodString>;
191
+ path: z.ZodString;
192
+ locale: z.ZodString;
193
+ version: z.ZodNumber;
194
+ publishedAt: z.ZodNullable<z.ZodString>;
195
+ data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
196
+ }, z.core.$strip>;
197
+ export type PublicContentWriteResponse = z.infer<typeof PublicContentWriteResponseSchema>;
198
+ export declare const PublicCreateContentRequestSchema: z.ZodObject<{
199
+ documentTypeId: z.ZodString;
200
+ parentId: z.ZodNullable<z.ZodString>;
201
+ slug: z.ZodString;
202
+ locale: z.ZodDefault<z.ZodString>;
203
+ isDefaultLocale: z.ZodDefault<z.ZodBoolean>;
204
+ translationGroupId: z.ZodOptional<z.ZodString>;
205
+ data: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
206
+ }, z.core.$strip>;
207
+ export type PublicCreateContentRequest = z.infer<typeof PublicCreateContentRequestSchema>;
208
+ export declare const PublicUpdateContentRequestSchema: z.ZodObject<{
209
+ data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
210
+ }, z.core.$strip>;
211
+ export type PublicUpdateContentRequest = z.infer<typeof PublicUpdateContentRequestSchema>;
@@ -0,0 +1,185 @@
1
+ import { z } from "zod";
2
+ // Session 112: serializer-contribution output. Keyed by pluginId —
3
+ // structurally separate from core fields and `data`, so a contribution
4
+ // can never remove or overwrite either. Present only when at least one
5
+ // active plugin's extendContentResponse produced a value.
6
+ export const PublicContentExtensionsSchema = z.record(z.string(), z.record(z.string(), z.unknown()));
7
+ // The public Content API's own wire contract (Month 9). Deliberately NOT
8
+ // a re-export of the backoffice ContentNode/ContentVersion shapes — the
9
+ // public surface exposes only what an external consumer needs, and can
10
+ // stay stable while internal shapes evolve. Session 103 widens this file.
11
+ // Session 116: `publishedAt` is nullable ONLY here — a verified preview
12
+ // token can serve a genuinely-draft node's latest version, which has no
13
+ // publishedAt. Every other public schema (summaries/lists) stays on the
14
+ // published-only surface and keeps its non-null publishedAt unchanged.
15
+ export const PublicContentItemSchema = z.object({
16
+ id: z.string().uuid(),
17
+ documentTypeId: z.string().uuid(),
18
+ locale: z.string().min(2),
19
+ publishedAt: z.string().datetime().nullable(),
20
+ version: z.number().int().positive(),
21
+ data: z.record(z.string(), z.unknown()),
22
+ extensions: PublicContentExtensionsSchema.optional(),
23
+ });
24
+ // Locale params mirror the backoffice contract exactly (content-api.schema):
25
+ // `fallback` is a fallback LOCALE (string), not a boolean — ?locale=ar&fallback=en.
26
+ // `previewToken` (Session 116) is a stateless signed token minted by
27
+ // POST /api/content/:id/preview-token; verified once per request against
28
+ // the FINAL resolved (post-locale) node id — see published-item.ts.
29
+ export const PublicContentItemQuerySchema = z.object({
30
+ locale: z.string().min(2).optional(),
31
+ fallback: z.string().min(2).optional(),
32
+ format: z.string().regex(/^[a-z0-9.-]+:[a-z0-9-]+$/).optional(),
33
+ previewToken: z.string().optional(),
34
+ });
35
+ // A custom-format read (?format=<pluginId>:<name>) — the plugin's whole
36
+ // projection rides in `content`; the caller asked for the plugin's shape,
37
+ // so the server imposes nothing beyond JSON-serializability.
38
+ export const PublicContentFormatResponseSchema = z.object({
39
+ format: z.string(),
40
+ content: z.unknown(),
41
+ });
42
+ export const PublicContentByPathQuerySchema = PublicContentItemQuerySchema.extend({
43
+ path: z.string().min(1).startsWith("/"),
44
+ });
45
+ export const PublicContentListQuerySchema = z.object({
46
+ cursor: z.string().uuid().optional(),
47
+ limit: z.coerce.number().int().min(1).max(100).default(50),
48
+ });
49
+ // The tree-walk row: everything a consumer needs to render navigation and
50
+ // fetch the full item — no version data (fetch by id for that), and
51
+ // publishedAt is non-nullable by construction (published-only surface).
52
+ export const PublicContentNodeSummarySchema = z.object({
53
+ id: z.string().uuid(),
54
+ parentId: z.string().uuid().nullable(),
55
+ path: z.string().min(1),
56
+ depth: z.number().int().nonnegative(),
57
+ sortOrder: z.number().int(),
58
+ documentTypeId: z.string().uuid(),
59
+ locale: z.string().min(2),
60
+ publishedAt: z.string().datetime(),
61
+ });
62
+ export const PublicContentListResponseSchema = z.object({
63
+ items: z.array(PublicContentNodeSummarySchema),
64
+ nextCursor: z.string().uuid().nullable(),
65
+ });
66
+ // GET /api/v1/content — combinable filters over the published surface.
67
+ // `under` is a published node's id; the server resolves it to a subtree
68
+ // path filter (strict descendants). q is a case-insensitive substring
69
+ // (ASCII-pinned), min 2 chars so a single char can't trigger full scans.
70
+ export const PublicContentSearchQuerySchema = z.object({
71
+ documentTypeId: z.string().uuid().optional(),
72
+ under: z.string().uuid().optional(),
73
+ q: z.string().min(2).optional(),
74
+ cursor: z.string().uuid().optional(),
75
+ limit: z.coerce.number().int().min(1).max(100).default(50),
76
+ });
77
+ // Public media (Month 9, Session 105). downloadUrl is generated per
78
+ // response — a fresh presigned GET, same convention as the backoffice
79
+ // MediaFileResponseSchema — never the persisted canonical url, never
80
+ // stored. filename/mimeType/size/uploadedAt are safe to expose as-is;
81
+ // uploadedBy (an internal user id) is deliberately omitted.
82
+ export const PublicMediaFileSchema = z.object({
83
+ id: z.string().uuid(),
84
+ filename: z.string().min(1),
85
+ mimeType: z.string().min(1),
86
+ size: z.number().int().nonnegative(),
87
+ downloadUrl: z.string().url(),
88
+ uploadedAt: z.string().datetime(),
89
+ });
90
+ export const PublicMediaListQuerySchema = z.object({
91
+ cursor: z.string().uuid().optional(),
92
+ limit: z.coerce.number().int().min(1).max(100).default(24),
93
+ search: z.string().min(1).optional(),
94
+ });
95
+ export const PublicMediaListResponseSchema = z.object({
96
+ items: z.array(PublicMediaFileSchema),
97
+ nextCursor: z.string().uuid().nullable(),
98
+ });
99
+ // Public document type introspection. Deliberately narrower than the
100
+ // backoffice DocumentTypeDefinitionSchema: tabs (admin-UI organization),
101
+ // treeRules (an admin content-placement rule), and defaultTemplateId (an
102
+ // editor pointer — the separate templates resource covers discovery) are
103
+ // all excluded. Just enough to interpret a fetched ContentVersion.data:
104
+ // each field's data key (id), display name, datatypeId, and its
105
+ // client-facing validation rules.
106
+ export const PublicFieldDefinitionSchema = z.object({
107
+ id: z.string(),
108
+ name: z.string().min(1),
109
+ datatypeId: z.string().min(1),
110
+ validation: z
111
+ .object({
112
+ required: z.boolean().optional(),
113
+ minLength: z.number().int().nonnegative().optional(),
114
+ maxLength: z.number().int().nonnegative().optional(),
115
+ min: z.number().optional(),
116
+ max: z.number().optional(),
117
+ pattern: z.string().min(1).optional(),
118
+ })
119
+ .optional(),
120
+ });
121
+ export const PublicDocumentTypeSchema = z.object({
122
+ id: z.string().uuid(),
123
+ name: z.string().min(1),
124
+ icon: z.string().min(1),
125
+ kind: z.enum(["page", "element"]),
126
+ fields: z.array(PublicFieldDefinitionSchema),
127
+ });
128
+ export const PublicDocumentTypeListQuerySchema = z.object({
129
+ cursor: z.string().uuid().optional(),
130
+ limit: z.coerce.number().int().min(1).max(100).default(50),
131
+ });
132
+ export const PublicDocumentTypeListResponseSchema = z.object({
133
+ items: z.array(PublicDocumentTypeSchema),
134
+ nextCursor: z.string().uuid().nullable(),
135
+ });
136
+ // Templates are inert data (headless-first decision) — the public shape
137
+ // is the same three fields the backoffice already exposes, defined fresh
138
+ // as its own contract rather than re-exporting TemplateDefinitionSchema.
139
+ export const PublicTemplateSchema = z.object({
140
+ id: z.string().uuid(),
141
+ name: z.string().min(1),
142
+ documentTypeId: z.string().uuid(),
143
+ });
144
+ export const PublicTemplateListQuerySchema = z.object({
145
+ cursor: z.string().uuid().optional(),
146
+ limit: z.coerce.number().int().min(1).max(100).default(50),
147
+ documentTypeId: z.string().uuid().optional(),
148
+ });
149
+ export const PublicTemplateListResponseSchema = z.object({
150
+ items: z.array(PublicTemplateSchema),
151
+ nextCursor: z.string().uuid().nullable(),
152
+ });
153
+ // Public content write shapes (Month 9, Session 107). The write surface is
154
+ // key-gated and NOT published-only — a writer operates on a node by id in
155
+ // any publish state, so `publishedAt` here is nullable (a fresh draft),
156
+ // unlike the read PublicContentItemSchema's non-null publishedAt.
157
+ export const PublicContentWriteResponseSchema = z.object({
158
+ id: z.string().uuid(),
159
+ documentTypeId: z.string().uuid(),
160
+ parentId: z.string().uuid().nullable(),
161
+ path: z.string().min(1),
162
+ locale: z.string().min(2),
163
+ version: z.number().int().positive(),
164
+ publishedAt: z.string().datetime().nullable(),
165
+ data: z.record(z.string(), z.unknown()),
166
+ });
167
+ // Create derives path/depth/sortOrder server-side from parentId + slug, so
168
+ // an external consumer never computes tree internals. `slug` is an
169
+ // already-slugified path segment; `data` defaults to {} (the stub-then-
170
+ // PATCH pattern). Non-empty data is field-validated at the route.
171
+ export const PublicCreateContentRequestSchema = z.object({
172
+ documentTypeId: z.string().uuid(),
173
+ parentId: z.string().uuid().nullable(),
174
+ slug: z.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),
175
+ locale: z.string().min(2).default("en"),
176
+ isDefaultLocale: z.boolean().default(true),
177
+ translationGroupId: z.string().uuid().optional(),
178
+ data: z.record(z.string(), z.unknown()).default({}),
179
+ });
180
+ // Body for both PUT (full-replace) and PATCH (partial merge) — the verb,
181
+ // not the body shape, decides the merge semantics. See the route
182
+ // descriptions.
183
+ export const PublicUpdateContentRequestSchema = z.object({
184
+ data: z.record(z.string(), z.unknown()),
185
+ });
@@ -0,0 +1,78 @@
1
+ import { z } from "zod";
2
+ export declare const BundledTemplateSchema: z.ZodObject<{
3
+ pluginId: z.ZodString;
4
+ version: z.ZodString;
5
+ name: z.ZodString;
6
+ description: z.ZodOptional<z.ZodString>;
7
+ sampleContent: z.ZodBoolean;
8
+ }, z.core.$strip>;
9
+ export type BundledTemplate = z.infer<typeof BundledTemplateSchema>;
10
+ export declare const SetupStatusResponseSchema: z.ZodObject<{
11
+ setupRequired: z.ZodBoolean;
12
+ bundledTemplates: z.ZodArray<z.ZodObject<{
13
+ pluginId: z.ZodString;
14
+ version: z.ZodString;
15
+ name: z.ZodString;
16
+ description: z.ZodOptional<z.ZodString>;
17
+ sampleContent: z.ZodBoolean;
18
+ }, z.core.$strip>>;
19
+ databaseConfigured: z.ZodBoolean;
20
+ }, z.core.$strip>;
21
+ export type SetupStatusResponse = z.infer<typeof SetupStatusResponseSchema>;
22
+ export declare const SetupStarterSelectionSchema: z.ZodObject<{
23
+ pluginId: z.ZodString;
24
+ includeSampleContent: z.ZodBoolean;
25
+ }, z.core.$strip>;
26
+ export type SetupStarterSelection = z.infer<typeof SetupStarterSelectionSchema>;
27
+ export declare const SetupCompleteRequestSchema: z.ZodObject<{
28
+ admin: z.ZodObject<{
29
+ email: z.ZodString;
30
+ name: z.ZodString;
31
+ password: z.ZodString;
32
+ }, z.core.$strip>;
33
+ database: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
34
+ dialect: z.ZodLiteral<"sqlite">;
35
+ filePath: z.ZodString;
36
+ }, z.core.$strip>, z.ZodObject<{
37
+ host: z.ZodString;
38
+ port: z.ZodCoercedNumber<unknown>;
39
+ database: z.ZodString;
40
+ username: z.ZodString;
41
+ password: z.ZodString;
42
+ dialect: z.ZodLiteral<"postgresql">;
43
+ }, z.core.$strip>, z.ZodObject<{
44
+ host: z.ZodString;
45
+ port: z.ZodCoercedNumber<unknown>;
46
+ database: z.ZodString;
47
+ username: z.ZodString;
48
+ password: z.ZodString;
49
+ dialect: z.ZodLiteral<"mysql">;
50
+ }, z.core.$strip>], "dialect">>;
51
+ starter: z.ZodOptional<z.ZodObject<{
52
+ pluginId: z.ZodString;
53
+ includeSampleContent: z.ZodBoolean;
54
+ }, z.core.$strip>>;
55
+ }, z.core.$strip>;
56
+ export type SetupCompleteRequest = z.infer<typeof SetupCompleteRequestSchema>;
57
+ export declare const SetupStarterResultSchema: z.ZodObject<{
58
+ pluginId: z.ZodString;
59
+ outcome: z.ZodEnum<{
60
+ installed: "installed";
61
+ failed: "failed";
62
+ }>;
63
+ reason: z.ZodOptional<z.ZodString>;
64
+ }, z.core.$strip>;
65
+ export type SetupStarterResult = z.infer<typeof SetupStarterResultSchema>;
66
+ export declare const SetupCompleteResponseSchema: z.ZodObject<{
67
+ success: z.ZodLiteral<true>;
68
+ starter: z.ZodOptional<z.ZodObject<{
69
+ pluginId: z.ZodString;
70
+ outcome: z.ZodEnum<{
71
+ installed: "installed";
72
+ failed: "failed";
73
+ }>;
74
+ reason: z.ZodOptional<z.ZodString>;
75
+ }, z.core.$strip>>;
76
+ configWarning: z.ZodOptional<z.ZodString>;
77
+ }, z.core.$strip>;
78
+ export type SetupCompleteResponse = z.infer<typeof SetupCompleteResponseSchema>;
@@ -0,0 +1,88 @@
1
+ import { z } from "zod";
2
+ // One bundled first-party starter template (currently only the blog
3
+ // template — apps/server/src/setup/bundled-templates.ts) offered from the
4
+ // setup wizard's optional "starter template" step. `pluginId` matches the
5
+ // template plugin's manifest id (e.g. "com.velora.blog") — the same id the
6
+ // marketplace install flow uses elsewhere, so a template picked here and a
7
+ // template found later in the marketplace are addressed identically.
8
+ // `sampleContent` reports whether the packed artifact carries a
9
+ // sample-content.json seed tree, not the content itself.
10
+ export const BundledTemplateSchema = z.object({
11
+ pluginId: z.string().min(1),
12
+ version: z.string().min(1),
13
+ name: z.string().min(1),
14
+ description: z.string().min(1).optional(),
15
+ sampleContent: z.boolean(),
16
+ });
17
+ export const SetupStatusResponseSchema = z.object({
18
+ setupRequired: z.boolean(),
19
+ // Always present — [] outside setup mode (a fully-configured instance has
20
+ // nothing left to offer here) and whenever nothing bundled is resolvable,
21
+ // never omitted or null.
22
+ bundledTemplates: z.array(BundledTemplateSchema),
23
+ // True when DATABASE_URL was already set at boot, so the wizard is
24
+ // running in its admin-only mode and must not render a database step.
25
+ // See the BootMode type and resolveBootMode function in
26
+ // apps/server/src/boot/resolve-boot-mode.ts for the three states.
27
+ databaseConfigured: z.boolean(),
28
+ });
29
+ const SqliteSelectionSchema = z.object({
30
+ dialect: z.literal("sqlite"),
31
+ filePath: z.string().min(1),
32
+ });
33
+ const ServerDialectSelectionSchema = z.object({
34
+ dialect: z.enum(["postgresql", "mysql"]),
35
+ host: z.string().min(1),
36
+ port: z.coerce.number().int().positive(),
37
+ database: z.string().min(1),
38
+ username: z.string().min(1),
39
+ password: z.string(),
40
+ });
41
+ // The wizard's optional starter step (Session 151): which bundled template
42
+ // to install during setup completion, and whether its sample-content.json
43
+ // tree should be seeded. Absent entirely = skip — never null.
44
+ export const SetupStarterSelectionSchema = z.object({
45
+ pluginId: z.string().min(1),
46
+ includeSampleContent: z.boolean(),
47
+ });
48
+ export const SetupCompleteRequestSchema = z.object({
49
+ admin: z.object({
50
+ email: z.string().email(),
51
+ name: z.string().min(1),
52
+ password: z.string().min(8),
53
+ }),
54
+ // Optional because the wizard has two shapes. On a fresh instance it
55
+ // collects a database selection; when DATABASE_URL was already injected
56
+ // the database is configured and read-only, and the request carries the
57
+ // admin only. The ROUTE enforces the pairing in both directions —
58
+ // routes/setup.ts — because "optional" alone would let a caller silently
59
+ // send a selection that is ignored.
60
+ database: z
61
+ .discriminatedUnion("dialect", [
62
+ SqliteSelectionSchema,
63
+ ServerDialectSelectionSchema.extend({ dialect: z.literal("postgresql") }),
64
+ ServerDialectSelectionSchema.extend({ dialect: z.literal("mysql") }),
65
+ ])
66
+ .optional(),
67
+ starter: SetupStarterSelectionSchema.optional(),
68
+ });
69
+ // What happened to the requested starter. "failed" never fails setup
70
+ // itself — the admin account and database config always stand — so this
71
+ // rides alongside success: true rather than replacing it. `reason` is only
72
+ // present on failure.
73
+ export const SetupStarterResultSchema = z.object({
74
+ pluginId: z.string().min(1),
75
+ outcome: z.enum(["installed", "failed"]),
76
+ reason: z.string().min(1).optional(),
77
+ });
78
+ export const SetupCompleteResponseSchema = z.object({
79
+ success: z.literal(true),
80
+ // ABSENT (not null) when no starter was requested — the skip-path
81
+ // response stays byte-identical to the pre-starter shape.
82
+ starter: SetupStarterResultSchema.optional(),
83
+ // ABSENT unless setup completed but could not write its configuration
84
+ // to disk. Setup itself still succeeded — the admin account and the
85
+ // provisioned database stand — so this rides alongside success: true
86
+ // rather than replacing it, exactly as `starter` does.
87
+ configWarning: z.string().min(1).optional(),
88
+ });
@@ -0,0 +1,43 @@
1
+ import { z } from "zod";
2
+ export declare const CreateSnapshotRequestSchema: z.ZodObject<{
3
+ label: z.ZodString;
4
+ description: z.ZodOptional<z.ZodString>;
5
+ }, z.core.$strip>;
6
+ export type CreateSnapshotRequest = z.infer<typeof CreateSnapshotRequestSchema>;
7
+ export declare const SnapshotResponseSchema: z.ZodObject<{
8
+ snapshot: z.ZodObject<{
9
+ id: z.ZodString;
10
+ createdAt: z.ZodString;
11
+ createdBy: z.ZodString;
12
+ label: z.ZodString;
13
+ description: z.ZodNullable<z.ZodString>;
14
+ }, z.core.$strip>;
15
+ }, z.core.$strip>;
16
+ export type SnapshotResponse = z.infer<typeof SnapshotResponseSchema>;
17
+ export declare const SnapshotListQuerySchema: z.ZodObject<{
18
+ cursor: z.ZodOptional<z.ZodString>;
19
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
20
+ }, z.core.$strip>;
21
+ export type SnapshotListQuery = z.infer<typeof SnapshotListQuerySchema>;
22
+ export declare const SnapshotListResponseSchema: z.ZodObject<{
23
+ items: z.ZodArray<z.ZodObject<{
24
+ id: z.ZodString;
25
+ createdAt: z.ZodString;
26
+ createdBy: z.ZodString;
27
+ label: z.ZodString;
28
+ description: z.ZodNullable<z.ZodString>;
29
+ }, z.core.$strip>>;
30
+ nextCursor: z.ZodNullable<z.ZodString>;
31
+ }, z.core.$strip>;
32
+ export type SnapshotListResponse = z.infer<typeof SnapshotListResponseSchema>;
33
+ export declare const RestoreSnapshotResponseSchema: z.ZodObject<{
34
+ snapshot: z.ZodObject<{
35
+ id: z.ZodString;
36
+ createdAt: z.ZodString;
37
+ createdBy: z.ZodString;
38
+ label: z.ZodString;
39
+ description: z.ZodNullable<z.ZodString>;
40
+ }, z.core.$strip>;
41
+ restoredItems: z.ZodNumber;
42
+ }, z.core.$strip>;
43
+ export type RestoreSnapshotResponse = z.infer<typeof RestoreSnapshotResponseSchema>;
@@ -0,0 +1,25 @@
1
+ import { z } from "zod";
2
+ import { SnapshotMetaSchema } from "./snapshot.schema.js";
3
+ // createdBy comes from the JWT, never the body (same rule as content).
4
+ export const CreateSnapshotRequestSchema = z.object({
5
+ label: z.string().min(1),
6
+ description: z.string().min(1).optional(),
7
+ });
8
+ export const SnapshotResponseSchema = z.object({
9
+ snapshot: SnapshotMetaSchema,
10
+ });
11
+ // Newest-first; cursor = id of the previous page's last snapshot.
12
+ export const SnapshotListQuerySchema = z.object({
13
+ cursor: z.string().uuid().optional(),
14
+ limit: z.coerce.number().int().min(1).max(100).default(20),
15
+ });
16
+ export const SnapshotListResponseSchema = z.object({
17
+ items: z.array(SnapshotMetaSchema),
18
+ // null = no more pages.
19
+ nextCursor: z.string().uuid().nullable(),
20
+ });
21
+ export const RestoreSnapshotResponseSchema = z.object({
22
+ snapshot: SnapshotMetaSchema,
23
+ // How many content nodes had their pointers repointed.
24
+ restoredItems: z.number().int().nonnegative(),
25
+ });
@@ -0,0 +1,28 @@
1
+ import { z } from "zod";
2
+ export declare const SnapshotItemSchema: z.ZodObject<{
3
+ contentId: z.ZodString;
4
+ version: z.ZodNumber;
5
+ publishedAt: z.ZodNullable<z.ZodString>;
6
+ }, z.core.$strip>;
7
+ export declare const SnapshotSchema: z.ZodObject<{
8
+ id: z.ZodString;
9
+ label: z.ZodString;
10
+ description: z.ZodNullable<z.ZodString>;
11
+ createdAt: z.ZodString;
12
+ createdBy: z.ZodString;
13
+ items: z.ZodArray<z.ZodObject<{
14
+ contentId: z.ZodString;
15
+ version: z.ZodNumber;
16
+ publishedAt: z.ZodNullable<z.ZodString>;
17
+ }, z.core.$strip>>;
18
+ }, z.core.$strip>;
19
+ export type SnapshotItem = z.infer<typeof SnapshotItemSchema>;
20
+ export type Snapshot = z.infer<typeof SnapshotSchema>;
21
+ export declare const SnapshotMetaSchema: z.ZodObject<{
22
+ id: z.ZodString;
23
+ createdAt: z.ZodString;
24
+ createdBy: z.ZodString;
25
+ label: z.ZodString;
26
+ description: z.ZodNullable<z.ZodString>;
27
+ }, z.core.$strip>;
28
+ export type SnapshotMeta = z.infer<typeof SnapshotMetaSchema>;
@@ -0,0 +1,17 @@
1
+ import { z } from "zod";
2
+ export const SnapshotItemSchema = z.object({
3
+ contentId: z.string().uuid(),
4
+ version: z.number().int().positive(),
5
+ publishedAt: z.string().datetime().nullable(),
6
+ });
7
+ export const SnapshotSchema = z.object({
8
+ id: z.string().uuid(),
9
+ label: z.string().min(1),
10
+ description: z.string().nullable(),
11
+ createdAt: z.string().datetime(),
12
+ createdBy: z.string().uuid(),
13
+ items: z.array(SnapshotItemSchema),
14
+ });
15
+ // Timeline listings — items excluded on purpose: a snapshot's items array
16
+ // scales with tree size and the timeline only needs the row facts.
17
+ export const SnapshotMetaSchema = SnapshotSchema.omit({ items: true });