@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.
- package/LICENSE +202 -0
- package/README.md +22 -0
- package/dist/api-error.schema.d.ts +5 -0
- package/dist/api-error.schema.js +6 -0
- package/dist/api-key-api.schema.d.ts +50 -0
- package/dist/api-key-api.schema.js +29 -0
- package/dist/auth.schema.d.ts +40 -0
- package/dist/auth.schema.js +30 -0
- package/dist/content-api.schema.d.ts +188 -0
- package/dist/content-api.schema.js +121 -0
- package/dist/content-trash-api.schema.d.ts +20 -0
- package/dist/content-trash-api.schema.js +23 -0
- package/dist/content-trash.schema.d.ts +31 -0
- package/dist/content-trash.schema.js +26 -0
- package/dist/content-version.schema.d.ts +11 -0
- package/dist/content-version.schema.js +10 -0
- package/dist/content.schema.d.ts +15 -0
- package/dist/content.schema.js +14 -0
- package/dist/data-type-api.schema.d.ts +36 -0
- package/dist/data-type-api.schema.js +32 -0
- package/dist/data-type-config.schema.d.ts +9 -0
- package/dist/data-type-config.schema.js +32 -0
- package/dist/document-type-api.schema.d.ts +202 -0
- package/dist/document-type-api.schema.js +86 -0
- package/dist/document-type.schema.d.ts +90 -0
- package/dist/document-type.schema.js +103 -0
- package/dist/health.schema.d.ts +6 -0
- package/dist/health.schema.js +5 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +27 -0
- package/dist/marketplace-listing-api.schema.d.ts +205 -0
- package/dist/marketplace-listing-api.schema.js +115 -0
- package/dist/media-api.schema.d.ts +36 -0
- package/dist/media-api.schema.js +23 -0
- package/dist/media.schema.d.ts +11 -0
- package/dist/media.schema.js +10 -0
- package/dist/plugin-management-api.schema.d.ts +145 -0
- package/dist/plugin-management-api.schema.js +186 -0
- package/dist/plugin-registry-api.schema.d.ts +31 -0
- package/dist/plugin-registry-api.schema.js +25 -0
- package/dist/plugin-storage-api.schema.d.ts +15 -0
- package/dist/plugin-storage-api.schema.js +24 -0
- package/dist/public-api.schema.d.ts +211 -0
- package/dist/public-api.schema.js +185 -0
- package/dist/setup-api.schema.d.ts +78 -0
- package/dist/setup-api.schema.js +88 -0
- package/dist/snapshot-api.schema.d.ts +43 -0
- package/dist/snapshot-api.schema.js +25 -0
- package/dist/snapshot.schema.d.ts +28 -0
- package/dist/snapshot.schema.js +17 -0
- package/dist/template-api.schema.d.ts +33 -0
- package/dist/template-api.schema.js +28 -0
- package/dist/template.schema.d.ts +7 -0
- package/dist/template.schema.js +13 -0
- package/dist/theme-api.schema.d.ts +21 -0
- package/dist/theme-api.schema.js +14 -0
- package/dist/user-api.schema.d.ts +79 -0
- package/dist/user-api.schema.js +36 -0
- 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 });
|