@relyio/sdk 0.2.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/CHANGELOG.md +13 -0
- package/LICENSE +201 -0
- package/README.md +314 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/chunk-2QUK2ZGD.js +738 -0
- package/dist/chunk-7W4MJXQ4.cjs +4429 -0
- package/dist/chunk-FJK7ZWKK.cjs +776 -0
- package/dist/chunk-HT6NFRM2.cjs +196 -0
- package/dist/chunk-I3ESNANB.js +177 -0
- package/dist/chunk-IY5LSKXU.js +3 -0
- package/dist/chunk-MWMSFIWN.cjs +17 -0
- package/dist/chunk-PPA2WWOH.cjs +4 -0
- package/dist/chunk-RJBIJ2ZK.js +4375 -0
- package/dist/chunk-XQ4QHWZE.js +13 -0
- package/dist/client/index.cjs +17 -0
- package/dist/client/index.d.cts +3 -0
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.js +4 -0
- package/dist/define-schema-DHvUCKwj.d.cts +2101 -0
- package/dist/define-schema-DHvUCKwj.d.ts +2101 -0
- package/dist/index-B-KiFHbx.d.ts +2708 -0
- package/dist/index-BsUqCAu8.d.cts +7855 -0
- package/dist/index-BsUqCAu8.d.ts +7855 -0
- package/dist/index-DGWaawHt.d.cts +2708 -0
- package/dist/index.cjs +499 -0
- package/dist/index.d.cts +523 -0
- package/dist/index.d.ts +523 -0
- package/dist/index.js +148 -0
- package/dist/react/index.cjs +4 -0
- package/dist/react/index.d.cts +2 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +3 -0
- package/dist/schema/index.cjs +157 -0
- package/dist/schema/index.d.cts +223 -0
- package/dist/schema/index.d.ts +223 -0
- package/dist/schema/index.js +4 -0
- package/dist/types/index.cjs +6 -0
- package/dist/types/index.d.cts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +3 -0
- package/dist/utils/index.cjs +81 -0
- package/dist/utils/index.d.cts +87 -0
- package/dist/utils/index.d.ts +87 -0
- package/dist/utils/index.js +4 -0
- package/package.json +159 -0
|
@@ -0,0 +1,2101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field type definitions matching @relyio/schema package
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* AI configuration. A single prompt — `instructions` — describes what the
|
|
6
|
+
* element is and how AI should produce its value. Attaches to fields, content
|
|
7
|
+
* types, components, fieldsets, and (extended) asset types.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* fields.richText('body', {
|
|
12
|
+
* ai: {
|
|
13
|
+
* instructions: `
|
|
14
|
+
* Write in a conversational tone.
|
|
15
|
+
* Use short paragraphs (2-3 sentences).
|
|
16
|
+
* Target grade 8 reading level.
|
|
17
|
+
* `
|
|
18
|
+
* }
|
|
19
|
+
* })
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
interface AIConfig {
|
|
23
|
+
/**
|
|
24
|
+
* AI brief for this element: what it should contain and how to produce it.
|
|
25
|
+
*
|
|
26
|
+
* Used by the Studio authoring agent and — on asset types with
|
|
27
|
+
* `ai.autoGenerate` — by the automatic post-upload run.
|
|
28
|
+
*
|
|
29
|
+
* The fallback chain for AI guidance is:
|
|
30
|
+
* 1. ai.instructions (most specific)
|
|
31
|
+
* 2. ui.description (general field description)
|
|
32
|
+
* 3. Field displayName + type (inferred from semantics)
|
|
33
|
+
*/
|
|
34
|
+
instructions?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Field-level AI config. `inputs` names the fields this instruction reads.
|
|
38
|
+
* Unknown ids and cycles are refused when the schema is parsed.
|
|
39
|
+
*/
|
|
40
|
+
interface FieldAIConfig extends AIConfig {
|
|
41
|
+
/** Field ids this instruction reads. Never inferred from instruction text. */
|
|
42
|
+
inputs?: string[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Asset-type AI configuration. Extends {@link AIConfig} with `autoGenerate`,
|
|
46
|
+
* the single switch that turns on automatic field generation after upload.
|
|
47
|
+
*/
|
|
48
|
+
interface AssetAIConfig extends AIConfig {
|
|
49
|
+
/**
|
|
50
|
+
* Master switch for automatic, post-upload field generation. When `true`, the
|
|
51
|
+
* derived analysis agent fills every field that declares `ai.instructions`,
|
|
52
|
+
* applied as a review proposal. Only meaningful for image asset types in v1.
|
|
53
|
+
*/
|
|
54
|
+
autoGenerate?: boolean;
|
|
55
|
+
}
|
|
56
|
+
interface BaseFieldConfig {
|
|
57
|
+
/** Whether the field is required */
|
|
58
|
+
required?: boolean;
|
|
59
|
+
/** Whether the field value must be unique */
|
|
60
|
+
unique?: boolean;
|
|
61
|
+
/** Default value for the field */
|
|
62
|
+
defaultValue?: unknown;
|
|
63
|
+
}
|
|
64
|
+
interface FieldUIConfig {
|
|
65
|
+
/** Display name shown in the UI */
|
|
66
|
+
displayName: string;
|
|
67
|
+
/** Field description/help text */
|
|
68
|
+
description?: string;
|
|
69
|
+
/** Widget-specific options */
|
|
70
|
+
options?: Record<string, unknown>;
|
|
71
|
+
}
|
|
72
|
+
interface RuleCondition {
|
|
73
|
+
field: string;
|
|
74
|
+
operator: 'equals' | 'not_equals' | 'contains' | 'not_contains' | 'greater_than' | 'less_than' | 'is_empty' | 'is_not_empty';
|
|
75
|
+
value?: unknown;
|
|
76
|
+
}
|
|
77
|
+
interface RuleConditions {
|
|
78
|
+
mode: 'all' | 'any' | 'none';
|
|
79
|
+
conditions: RuleCondition[];
|
|
80
|
+
}
|
|
81
|
+
interface VisibilityRule {
|
|
82
|
+
type: 'visibility';
|
|
83
|
+
action: 'show' | 'hide';
|
|
84
|
+
conditions: RuleConditions;
|
|
85
|
+
}
|
|
86
|
+
interface RequirementRule {
|
|
87
|
+
type: 'requirement';
|
|
88
|
+
action: 'require' | 'optional';
|
|
89
|
+
conditions: RuleConditions;
|
|
90
|
+
}
|
|
91
|
+
interface ValidationRule {
|
|
92
|
+
type: 'validation';
|
|
93
|
+
action: 'validate' | 'skip';
|
|
94
|
+
message?: string;
|
|
95
|
+
conditions: RuleConditions;
|
|
96
|
+
}
|
|
97
|
+
interface ReadOnlyRule {
|
|
98
|
+
type: 'readOnly';
|
|
99
|
+
action: 'enable' | 'disable';
|
|
100
|
+
conditions: RuleConditions;
|
|
101
|
+
}
|
|
102
|
+
type FieldRule = VisibilityRule | RequirementRule | ValidationRule | ReadOnlyRule;
|
|
103
|
+
type LocalizationConfig = boolean | string[] | {
|
|
104
|
+
enabled: boolean;
|
|
105
|
+
requiredLocales?: string[];
|
|
106
|
+
fallback?: boolean;
|
|
107
|
+
};
|
|
108
|
+
interface FieldDefinition<TId extends string = string, TType extends string = string, TConfig = unknown> {
|
|
109
|
+
/** Unique field identifier - preserves literal type for type inference */
|
|
110
|
+
readonly id: TId;
|
|
111
|
+
/** Field type */
|
|
112
|
+
readonly type: TType;
|
|
113
|
+
/** Type-specific configuration */
|
|
114
|
+
config?: TConfig;
|
|
115
|
+
/** UI display configuration */
|
|
116
|
+
ui?: FieldUIConfig;
|
|
117
|
+
/** AI configuration: generation/review guidance for this field */
|
|
118
|
+
ai?: FieldAIConfig;
|
|
119
|
+
/** Dynamic field rules */
|
|
120
|
+
rules?: FieldRule[];
|
|
121
|
+
/** Localization settings */
|
|
122
|
+
localization?: LocalizationConfig;
|
|
123
|
+
/** Fallback value when field is empty */
|
|
124
|
+
fallback?: unknown;
|
|
125
|
+
/** Whether this field is deprecated */
|
|
126
|
+
deprecated?: boolean;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Any field definition - used in arrays where we need to preserve specific field types
|
|
130
|
+
*/
|
|
131
|
+
type AnyFieldDefinition = FieldDefinition<string, string, unknown>;
|
|
132
|
+
interface ShortTextConfig extends BaseFieldConfig {
|
|
133
|
+
/** Maximum character length */
|
|
134
|
+
maxLength?: number;
|
|
135
|
+
/** Regex pattern for validation */
|
|
136
|
+
pattern?: string;
|
|
137
|
+
}
|
|
138
|
+
interface LongTextConfig extends BaseFieldConfig {
|
|
139
|
+
minLength?: number;
|
|
140
|
+
maxLength?: number;
|
|
141
|
+
}
|
|
142
|
+
interface RichTextConfig extends BaseFieldConfig {
|
|
143
|
+
/** Maximum character length for the rich text content */
|
|
144
|
+
maxLength?: number;
|
|
145
|
+
/** Allowed formatting options (e.g., bold, italic, underline) */
|
|
146
|
+
allowedFormats?: string[];
|
|
147
|
+
/** Allowed embed types (e.g., image, video, code) */
|
|
148
|
+
embedTypes?: string[];
|
|
149
|
+
}
|
|
150
|
+
interface SlugConfig extends BaseFieldConfig {
|
|
151
|
+
/** Source field to generate slug from */
|
|
152
|
+
sourceField?: string;
|
|
153
|
+
/** Maximum character length */
|
|
154
|
+
maxLength?: number;
|
|
155
|
+
}
|
|
156
|
+
interface UrlConfig extends BaseFieldConfig {
|
|
157
|
+
/** Allowed URL protocols */
|
|
158
|
+
allowedProtocols?: ('http' | 'https' | 'ftp' | 'ftps')[];
|
|
159
|
+
/** Maximum character length */
|
|
160
|
+
maxLength?: number;
|
|
161
|
+
}
|
|
162
|
+
interface EmailConfig extends BaseFieldConfig {
|
|
163
|
+
/** Maximum character length */
|
|
164
|
+
maxLength?: number;
|
|
165
|
+
/** Whitelist of allowed email domains */
|
|
166
|
+
domainWhitelist?: string[];
|
|
167
|
+
}
|
|
168
|
+
interface IntegerConfig extends BaseFieldConfig {
|
|
169
|
+
min?: number;
|
|
170
|
+
max?: number;
|
|
171
|
+
}
|
|
172
|
+
interface DecimalConfig extends BaseFieldConfig {
|
|
173
|
+
min?: number;
|
|
174
|
+
max?: number;
|
|
175
|
+
decimalPlaces?: number;
|
|
176
|
+
roundingMode?: 'HALF_UP' | 'FLOOR' | 'CEILING' | 'ROUND' | 'TRUNCATE';
|
|
177
|
+
}
|
|
178
|
+
interface BooleanConfig extends BaseFieldConfig {
|
|
179
|
+
trueLabel?: string;
|
|
180
|
+
falseLabel?: string;
|
|
181
|
+
}
|
|
182
|
+
interface EnumConfig extends BaseFieldConfig {
|
|
183
|
+
options: Array<{
|
|
184
|
+
value: string;
|
|
185
|
+
label?: string;
|
|
186
|
+
}>;
|
|
187
|
+
multi?: boolean;
|
|
188
|
+
}
|
|
189
|
+
interface DateConfig extends BaseFieldConfig {
|
|
190
|
+
minDate?: string;
|
|
191
|
+
maxDate?: string;
|
|
192
|
+
format?: string;
|
|
193
|
+
}
|
|
194
|
+
interface DateTimeConfig extends BaseFieldConfig {
|
|
195
|
+
minDateTime?: string;
|
|
196
|
+
maxDateTime?: string;
|
|
197
|
+
format?: string;
|
|
198
|
+
timezone?: boolean;
|
|
199
|
+
}
|
|
200
|
+
interface ReferenceConfig extends BaseFieldConfig {
|
|
201
|
+
/**
|
|
202
|
+
* Target entry type id(s) — content type or asset type ids. Pass a single id
|
|
203
|
+
* for one target or an array for several. All ids must belong to the same
|
|
204
|
+
* family (all content types or all asset types).
|
|
205
|
+
*/
|
|
206
|
+
to: string | string[];
|
|
207
|
+
/** Allow multiple references (the field value is a list). */
|
|
208
|
+
multi?: boolean;
|
|
209
|
+
/** Reference strength for publish/unpublish behavior. */
|
|
210
|
+
referenceStrength?: 'strong' | 'weak';
|
|
211
|
+
/** Behavior when a referenced entry is deleted. */
|
|
212
|
+
onTargetDelete?: 'block' | 'nullify';
|
|
213
|
+
}
|
|
214
|
+
interface TagsConfig extends BaseFieldConfig {
|
|
215
|
+
allowCustom?: boolean;
|
|
216
|
+
predefinedTags?: string[];
|
|
217
|
+
maxTags?: number;
|
|
218
|
+
}
|
|
219
|
+
interface ListConfig extends BaseFieldConfig {
|
|
220
|
+
dragAndDrop?: boolean;
|
|
221
|
+
minItems?: number;
|
|
222
|
+
maxItems?: number;
|
|
223
|
+
/** Subfields for list items */
|
|
224
|
+
subfields?: FieldDefinition[];
|
|
225
|
+
}
|
|
226
|
+
type FieldType = 'shortText' | 'longText' | 'richText' | 'slug' | 'url' | 'email' | 'integer' | 'decimal' | 'boolean' | 'enum' | 'date' | 'dateTime' | 'reference' | 'tags' | 'list';
|
|
227
|
+
type ComponentFieldType = `component(${string})`;
|
|
228
|
+
type AllFieldTypes = FieldType | ComponentFieldType;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Workflow definition for content approval pipelines
|
|
232
|
+
*
|
|
233
|
+
* Workflows define approval stages that content must pass through before
|
|
234
|
+
* publication. They can be configured globally and per content type.
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* // Simple workflow with one approval stage
|
|
238
|
+
* const workflow = defineWorkflow({
|
|
239
|
+
* enabled: true,
|
|
240
|
+
* stages: [
|
|
241
|
+
* defineWorkflowStage('review', {
|
|
242
|
+
* displayName: 'Editorial Review',
|
|
243
|
+
* allowedRoles: ['editor', 'admin']
|
|
244
|
+
* })
|
|
245
|
+
* ]
|
|
246
|
+
* })
|
|
247
|
+
*
|
|
248
|
+
* @example
|
|
249
|
+
* // Multi-stage workflow
|
|
250
|
+
* const workflow = defineWorkflow({
|
|
251
|
+
* enabled: true,
|
|
252
|
+
* stages: [
|
|
253
|
+
* defineWorkflowStage('editorial-review', {
|
|
254
|
+
* displayName: 'Editorial Review',
|
|
255
|
+
* allowedRoles: ['editor']
|
|
256
|
+
* }),
|
|
257
|
+
* defineWorkflowStage('legal-approval', {
|
|
258
|
+
* displayName: 'Legal Approval',
|
|
259
|
+
* requiredApprovals: 1,
|
|
260
|
+
* allowedRoles: ['legal-reviewer']
|
|
261
|
+
* }),
|
|
262
|
+
* defineWorkflowStage('final-approval', {
|
|
263
|
+
* displayName: 'Final Approval',
|
|
264
|
+
* requiredApprovals: 2,
|
|
265
|
+
* allowedRoles: ['publisher', 'admin']
|
|
266
|
+
* })
|
|
267
|
+
* ]
|
|
268
|
+
* })
|
|
269
|
+
*/
|
|
270
|
+
/**
|
|
271
|
+
* Escalation configuration when a workflow stage times out
|
|
272
|
+
*/
|
|
273
|
+
interface WorkflowEscalation {
|
|
274
|
+
/** Roles to notify when stage times out */
|
|
275
|
+
notifyRoles?: string[];
|
|
276
|
+
/** Roles to escalate to if still pending after another timeout period */
|
|
277
|
+
escalateToRoles?: string[];
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Auto-assignment configuration for workflow stages
|
|
281
|
+
*/
|
|
282
|
+
interface WorkflowAutoAssign {
|
|
283
|
+
/** Roles whose users should be notified when content enters this stage */
|
|
284
|
+
roles: string[];
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Workflow stage configuration
|
|
288
|
+
*/
|
|
289
|
+
interface WorkflowStageConfig {
|
|
290
|
+
/** Human-readable name shown in Studio */
|
|
291
|
+
displayName: string;
|
|
292
|
+
/** Optional description for reviewers */
|
|
293
|
+
description?: string;
|
|
294
|
+
/** Number of approvals needed to pass this stage (default: 1) */
|
|
295
|
+
requiredApprovals?: number;
|
|
296
|
+
/** Roles that can approve this stage */
|
|
297
|
+
allowedRoles?: string[];
|
|
298
|
+
/** Auto-assignment configuration */
|
|
299
|
+
autoAssign?: WorkflowAutoAssign;
|
|
300
|
+
/** Days before escalation triggers (optional) */
|
|
301
|
+
timeoutDays?: number;
|
|
302
|
+
/** Escalation configuration when stage times out */
|
|
303
|
+
escalation?: WorkflowEscalation;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Complete workflow stage definition
|
|
307
|
+
*/
|
|
308
|
+
interface WorkflowStageDefinition {
|
|
309
|
+
readonly _tag: 'workflowStage';
|
|
310
|
+
readonly id: string;
|
|
311
|
+
readonly displayName: string;
|
|
312
|
+
readonly description?: string;
|
|
313
|
+
readonly requiredApprovals: number;
|
|
314
|
+
readonly allowedRoles?: string[];
|
|
315
|
+
readonly autoAssign?: WorkflowAutoAssign;
|
|
316
|
+
readonly timeoutDays?: number;
|
|
317
|
+
readonly escalation?: WorkflowEscalation;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Workflow configuration
|
|
321
|
+
*/
|
|
322
|
+
interface WorkflowConfig {
|
|
323
|
+
/** Enable/disable workflow for the branch (default: false) */
|
|
324
|
+
enabled?: boolean;
|
|
325
|
+
/** Array of approval stage definitions */
|
|
326
|
+
stages?: WorkflowStageDefinition[];
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Complete workflow definition
|
|
330
|
+
*/
|
|
331
|
+
interface WorkflowDefinition {
|
|
332
|
+
readonly _tag: 'workflow';
|
|
333
|
+
readonly enabled: boolean;
|
|
334
|
+
readonly stages: WorkflowStageDefinition[];
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Per-content-type workflow configuration
|
|
338
|
+
*/
|
|
339
|
+
interface ContentTypeWorkflowConfig {
|
|
340
|
+
/** Enable workflow for this content type (inherits from global if not set) */
|
|
341
|
+
enabled?: boolean;
|
|
342
|
+
/** Which global stages apply to this content type (subset of global stages) */
|
|
343
|
+
stages?: string[];
|
|
344
|
+
/** Publish automatically after all stages are approved */
|
|
345
|
+
autoPublish?: boolean;
|
|
346
|
+
/** Require all locales to be approved before publishing */
|
|
347
|
+
requireAllLocales?: boolean;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Define a workflow stage
|
|
351
|
+
*
|
|
352
|
+
* @param id - Unique identifier for the stage (kebab-case or camelCase)
|
|
353
|
+
* @param config - Stage configuration
|
|
354
|
+
*
|
|
355
|
+
* @example
|
|
356
|
+
* const editorialReview = defineWorkflowStage('editorial-review', {
|
|
357
|
+
* displayName: 'Editorial Review',
|
|
358
|
+
* description: 'Content quality and style check',
|
|
359
|
+
* requiredApprovals: 1,
|
|
360
|
+
* allowedRoles: ['editor', 'senior-editor']
|
|
361
|
+
* })
|
|
362
|
+
*
|
|
363
|
+
* @example
|
|
364
|
+
* // Stage with auto-assignment and timeout
|
|
365
|
+
* const legalApproval = defineWorkflowStage('legal-approval', {
|
|
366
|
+
* displayName: 'Legal Approval',
|
|
367
|
+
* allowedRoles: ['legal-reviewer'],
|
|
368
|
+
* autoAssign: { roles: ['legal-reviewer'] },
|
|
369
|
+
* timeoutDays: 3,
|
|
370
|
+
* escalation: {
|
|
371
|
+
* notifyRoles: ['legal-reviewer'],
|
|
372
|
+
* escalateToRoles: ['admin']
|
|
373
|
+
* }
|
|
374
|
+
* })
|
|
375
|
+
*/
|
|
376
|
+
declare function defineWorkflowStage(id: string, config: WorkflowStageConfig): WorkflowStageDefinition;
|
|
377
|
+
/**
|
|
378
|
+
* Define a workflow configuration
|
|
379
|
+
*
|
|
380
|
+
* @param config - Workflow configuration with enabled flag and stages
|
|
381
|
+
*
|
|
382
|
+
* @example
|
|
383
|
+
* // Simple workflow
|
|
384
|
+
* const workflow = defineWorkflow({
|
|
385
|
+
* enabled: true,
|
|
386
|
+
* stages: [
|
|
387
|
+
* defineWorkflowStage('review', {
|
|
388
|
+
* displayName: 'Review',
|
|
389
|
+
* allowedRoles: ['editor']
|
|
390
|
+
* })
|
|
391
|
+
* ]
|
|
392
|
+
* })
|
|
393
|
+
*
|
|
394
|
+
* @example
|
|
395
|
+
* // Disabled workflow (direct publish)
|
|
396
|
+
* const workflow = defineWorkflow({
|
|
397
|
+
* enabled: false
|
|
398
|
+
* })
|
|
399
|
+
*/
|
|
400
|
+
declare function defineWorkflow(config: WorkflowConfig): WorkflowDefinition;
|
|
401
|
+
/**
|
|
402
|
+
* Define content-type specific workflow configuration
|
|
403
|
+
*
|
|
404
|
+
* @param config - Content type workflow configuration
|
|
405
|
+
*
|
|
406
|
+
* @example
|
|
407
|
+
* // Use specific stages from global workflow
|
|
408
|
+
* const blogPostWorkflow = defineContentTypeWorkflow({
|
|
409
|
+
* enabled: true,
|
|
410
|
+
* stages: ['editorial-review', 'final-approval'], // Skip legal
|
|
411
|
+
* autoPublish: false
|
|
412
|
+
* })
|
|
413
|
+
*
|
|
414
|
+
* @example
|
|
415
|
+
* // Disable workflow for this content type
|
|
416
|
+
* const quickUpdateWorkflow = defineContentTypeWorkflow({
|
|
417
|
+
* enabled: false
|
|
418
|
+
* })
|
|
419
|
+
*
|
|
420
|
+
* @example
|
|
421
|
+
* // Require all locales to be approved
|
|
422
|
+
* const marketingPageWorkflow = defineContentTypeWorkflow({
|
|
423
|
+
* enabled: true,
|
|
424
|
+
* stages: ['translation-review', 'regional-approval'],
|
|
425
|
+
* requireAllLocales: true
|
|
426
|
+
* })
|
|
427
|
+
*/
|
|
428
|
+
declare function defineContentTypeWorkflow(config: ContentTypeWorkflowConfig): ContentTypeWorkflowConfig;
|
|
429
|
+
/**
|
|
430
|
+
* Check if a value is a workflow stage definition
|
|
431
|
+
*/
|
|
432
|
+
declare function isWorkflowStageDefinition(value: unknown): value is WorkflowStageDefinition;
|
|
433
|
+
/**
|
|
434
|
+
* Check if a value is a workflow definition
|
|
435
|
+
*/
|
|
436
|
+
declare function isWorkflowDefinition(value: unknown): value is WorkflowDefinition;
|
|
437
|
+
/**
|
|
438
|
+
* Get all stage IDs from a workflow definition
|
|
439
|
+
*/
|
|
440
|
+
declare function getWorkflowStageIds(workflow: WorkflowDefinition): string[];
|
|
441
|
+
/**
|
|
442
|
+
* Find a stage by ID in a workflow definition
|
|
443
|
+
*/
|
|
444
|
+
declare function findWorkflowStage(workflow: WorkflowDefinition, stageId: string): WorkflowStageDefinition | undefined;
|
|
445
|
+
/**
|
|
446
|
+
* Get the next stage after a given stage ID (null if last stage)
|
|
447
|
+
*/
|
|
448
|
+
declare function getNextWorkflowStage(workflow: WorkflowDefinition, currentStageId: string): WorkflowStageDefinition | null;
|
|
449
|
+
/**
|
|
450
|
+
* Get the first stage in the workflow (null if no stages)
|
|
451
|
+
*/
|
|
452
|
+
declare function getFirstWorkflowStage(workflow: WorkflowDefinition): WorkflowStageDefinition | null;
|
|
453
|
+
/**
|
|
454
|
+
* Check if a stage is the final stage in the workflow
|
|
455
|
+
*/
|
|
456
|
+
declare function isFinalWorkflowStage(workflow: WorkflowDefinition, stageId: string): boolean;
|
|
457
|
+
/**
|
|
458
|
+
* Convert a workflow definition to JSON-safe format (strips _tag)
|
|
459
|
+
*/
|
|
460
|
+
declare function workflowToJSON(workflow: WorkflowDefinition): {
|
|
461
|
+
enabled: boolean;
|
|
462
|
+
stages?: Array<Omit<WorkflowStageDefinition, '_tag'>>;
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Content type definition matching @relyio/schema ContentTypeSchema
|
|
467
|
+
*
|
|
468
|
+
* Uses advanced TypeScript generics to preserve literal field IDs through
|
|
469
|
+
* the type system, enabling full autocomplete in SDK methods like where().
|
|
470
|
+
*/
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Fieldset for organizing related fields
|
|
474
|
+
* Generic over fields to preserve literal field IDs
|
|
475
|
+
*/
|
|
476
|
+
interface Fieldset<TFields extends readonly AnyFieldDefinition[] = readonly AnyFieldDefinition[]> {
|
|
477
|
+
/** Unique fieldset identifier */
|
|
478
|
+
readonly id: string;
|
|
479
|
+
/** Display name shown in the UI */
|
|
480
|
+
readonly displayName: string;
|
|
481
|
+
/** Optional description */
|
|
482
|
+
readonly description?: string;
|
|
483
|
+
/** AI configuration for content generation and review */
|
|
484
|
+
readonly ai?: AIConfig;
|
|
485
|
+
/** Fields within this fieldset - preserves literal types */
|
|
486
|
+
readonly fields: TFields;
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Type alias for a fieldset with any fields.
|
|
490
|
+
* Used in generic constraints where we need to accept any fieldset type.
|
|
491
|
+
*/
|
|
492
|
+
type AnyFieldset$2 = Fieldset<any>;
|
|
493
|
+
/**
|
|
494
|
+
* Create a fieldset for organizing fields
|
|
495
|
+
* Generic to preserve the specific field types for type inference
|
|
496
|
+
*
|
|
497
|
+
* @example
|
|
498
|
+
* const seoFieldset = fieldset('seo', {
|
|
499
|
+
* displayName: 'SEO Settings',
|
|
500
|
+
* fields: [
|
|
501
|
+
* fields.shortText('metaTitle', { config: { maxLength: 60 } }),
|
|
502
|
+
* fields.longText('metaDescription', { config: { maxLength: 160 } }),
|
|
503
|
+
* ]
|
|
504
|
+
* })
|
|
505
|
+
*/
|
|
506
|
+
declare function fieldset<TFields extends readonly AnyFieldDefinition[]>(id: string, config: {
|
|
507
|
+
displayName: string;
|
|
508
|
+
description?: string;
|
|
509
|
+
ai?: AIConfig;
|
|
510
|
+
fields: TFields;
|
|
511
|
+
}): Fieldset<TFields>;
|
|
512
|
+
/**
|
|
513
|
+
* Content type configuration using direct fields
|
|
514
|
+
* Generic to preserve literal field IDs for type inference
|
|
515
|
+
*/
|
|
516
|
+
interface ContentTypeConfigWithFields<TFields extends readonly AnyFieldDefinition[] = readonly AnyFieldDefinition[]> {
|
|
517
|
+
/** Display name shown in the UI */
|
|
518
|
+
displayName: string;
|
|
519
|
+
/** Plural display name shown in the UI (e.g., "Products" for "Product") */
|
|
520
|
+
displayNamePlural?: string;
|
|
521
|
+
/** Description of the content type */
|
|
522
|
+
description?: string;
|
|
523
|
+
/** AI configuration: generation/review guidance */
|
|
524
|
+
ai?: AIConfig;
|
|
525
|
+
/**
|
|
526
|
+
* Field ID to use as entry display title in lists, references, and editor header.
|
|
527
|
+
* If not set, falls back to: title → name → slug → first shortText field → entryUid
|
|
528
|
+
*/
|
|
529
|
+
displayField?: string;
|
|
530
|
+
/** Whether this content type supports hierarchical (parent-child) relationships */
|
|
531
|
+
hierarchical?: boolean;
|
|
532
|
+
/** Access tags for role-based access control */
|
|
533
|
+
accessTags?: string[];
|
|
534
|
+
/** Workflow configuration for this content type */
|
|
535
|
+
workflow?: ContentTypeWorkflowConfig;
|
|
536
|
+
/** Direct field definitions - preserves literal types */
|
|
537
|
+
fields: TFields;
|
|
538
|
+
/** Cannot have fieldsets when using fields */
|
|
539
|
+
fieldsets?: never;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Content type configuration using fieldsets
|
|
543
|
+
* Generic to preserve fieldset field types
|
|
544
|
+
*/
|
|
545
|
+
interface ContentTypeConfigWithFieldsets<TFieldsets extends readonly AnyFieldset$2[] = readonly AnyFieldset$2[]> {
|
|
546
|
+
/** Display name shown in the UI */
|
|
547
|
+
displayName: string;
|
|
548
|
+
/** Plural display name shown in the UI (e.g., "Products" for "Product") */
|
|
549
|
+
displayNamePlural?: string;
|
|
550
|
+
/** Description of the content type */
|
|
551
|
+
description?: string;
|
|
552
|
+
/** AI configuration: generation/review guidance */
|
|
553
|
+
ai?: AIConfig;
|
|
554
|
+
/**
|
|
555
|
+
* Field ID to use as entry display title in lists, references, and editor header.
|
|
556
|
+
* If not set, falls back to: title → name → slug → first shortText field → entryUid
|
|
557
|
+
*/
|
|
558
|
+
displayField?: string;
|
|
559
|
+
/** Access tags for role-based access control */
|
|
560
|
+
accessTags?: string[];
|
|
561
|
+
/** Whether this content type supports hierarchical (parent-child) relationships */
|
|
562
|
+
hierarchical?: boolean;
|
|
563
|
+
/** Workflow configuration for this content type */
|
|
564
|
+
workflow?: ContentTypeWorkflowConfig;
|
|
565
|
+
/** Field organization via fieldsets - preserves literal types */
|
|
566
|
+
fieldsets: TFieldsets;
|
|
567
|
+
/** Cannot have direct fields when using fieldsets */
|
|
568
|
+
fields?: never;
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Content type configuration (either fields OR fieldsets, not both)
|
|
572
|
+
*/
|
|
573
|
+
type ContentTypeConfig<TFields extends readonly AnyFieldDefinition[] = readonly AnyFieldDefinition[], TFieldsets extends readonly AnyFieldset$2[] = readonly AnyFieldset$2[]> = ContentTypeConfigWithFields<TFields> | ContentTypeConfigWithFieldsets<TFieldsets>;
|
|
574
|
+
/**
|
|
575
|
+
* Content type definition - preserves field types for inference
|
|
576
|
+
*/
|
|
577
|
+
interface ContentTypeDefinition<TFields extends readonly AnyFieldDefinition[] = readonly AnyFieldDefinition[], TFieldsets extends readonly AnyFieldset$2[] = readonly AnyFieldset$2[]> {
|
|
578
|
+
readonly _tag: 'contentType';
|
|
579
|
+
readonly name: string;
|
|
580
|
+
readonly displayName: string;
|
|
581
|
+
readonly displayNamePlural?: string;
|
|
582
|
+
readonly description?: string;
|
|
583
|
+
/** AI configuration: generation/review guidance */
|
|
584
|
+
readonly ai?: AIConfig;
|
|
585
|
+
/** Field ID to use as entry display title */
|
|
586
|
+
readonly displayField?: string;
|
|
587
|
+
readonly hierarchical: boolean;
|
|
588
|
+
readonly accessTags?: string[];
|
|
589
|
+
readonly workflow?: ContentTypeWorkflowConfig;
|
|
590
|
+
readonly fields?: TFields;
|
|
591
|
+
readonly fieldsets?: TFieldsets;
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Define a content type with type-safe fields
|
|
595
|
+
*
|
|
596
|
+
* The generic type parameters preserve the literal field IDs through the type
|
|
597
|
+
* system, enabling autocomplete in SDK methods like where(), select(), etc.
|
|
598
|
+
*
|
|
599
|
+
* @example
|
|
600
|
+
* // Using direct fields
|
|
601
|
+
* const product = defineContentType('product', {
|
|
602
|
+
* displayName: 'Product',
|
|
603
|
+
* fields: [
|
|
604
|
+
* fields.shortText('title', { config: { required: true } }),
|
|
605
|
+
* fields.currency('price', { config: { currencyCode: 'USD' } }),
|
|
606
|
+
* ]
|
|
607
|
+
* })
|
|
608
|
+
*
|
|
609
|
+
* @example
|
|
610
|
+
* // Using fieldsets for organization
|
|
611
|
+
* const product = defineContentType('product', {
|
|
612
|
+
* displayName: 'Product',
|
|
613
|
+
* fieldsets: [
|
|
614
|
+
* fieldset('basic', {
|
|
615
|
+
* displayName: 'Basic Info',
|
|
616
|
+
* fields: [
|
|
617
|
+
* fields.shortText('title', { config: { required: true } }),
|
|
618
|
+
* ]
|
|
619
|
+
* }),
|
|
620
|
+
* fieldset('pricing', {
|
|
621
|
+
* displayName: 'Pricing',
|
|
622
|
+
* fields: [
|
|
623
|
+
* fields.currency('price', { config: { currencyCode: 'USD' } }),
|
|
624
|
+
* ]
|
|
625
|
+
* }),
|
|
626
|
+
* ]
|
|
627
|
+
* })
|
|
628
|
+
*/
|
|
629
|
+
declare function defineContentType<TFields extends readonly AnyFieldDefinition[], _TFieldsets extends readonly Fieldset<AnyFieldDefinition[]>[]>(name: string, config: ContentTypeConfigWithFields<TFields>): ContentTypeDefinition<TFields, readonly []>;
|
|
630
|
+
declare function defineContentType<_TFields extends readonly AnyFieldDefinition[], TFieldsets extends readonly Fieldset<AnyFieldDefinition[]>[]>(name: string, config: ContentTypeConfigWithFieldsets<TFieldsets>): ContentTypeDefinition<readonly [], TFieldsets>;
|
|
631
|
+
/**
|
|
632
|
+
* Type alias for any content type definition.
|
|
633
|
+
*/
|
|
634
|
+
type AnyContentTypeDefinition = ContentTypeDefinition<any, any>;
|
|
635
|
+
/**
|
|
636
|
+
* Extract field IDs from a content type definition
|
|
637
|
+
* Works with both direct fields and fieldsets
|
|
638
|
+
*/
|
|
639
|
+
type ExtractFieldIds<T extends AnyContentTypeDefinition> = NonNullable<T['fields']> extends (infer F)[] ? F extends AnyFieldDefinition ? F['id'] : ExtractFromFieldsets<T> : ExtractFromFieldsets<T>;
|
|
640
|
+
type ExtractFromFieldsets<T extends AnyContentTypeDefinition> = NonNullable<T['fieldsets']> extends (infer FS)[] ? FS extends Fieldset<infer Fields> ? Fields extends AnyFieldDefinition[] ? Fields[number]['id'] : never : never : never;
|
|
641
|
+
/**
|
|
642
|
+
* Entry metadata that's present on all content entries
|
|
643
|
+
*/
|
|
644
|
+
interface EntryMetadata {
|
|
645
|
+
/** Unique entry identifier */
|
|
646
|
+
id: string;
|
|
647
|
+
/** Content type id (API field name is `type`) */
|
|
648
|
+
type: string;
|
|
649
|
+
/** Entry type (content, asset, singleton, settings) */
|
|
650
|
+
entryType: string;
|
|
651
|
+
/**
|
|
652
|
+
* Container lifecycle only (`active` | `archived` | `proposed`).
|
|
653
|
+
* Publication is `localeStatus` (`INV-LM-STATUS-IS-TWO-FIELDS`).
|
|
654
|
+
*/
|
|
655
|
+
status: 'active' | 'archived' | 'proposed';
|
|
656
|
+
/** Per-locale version number */
|
|
657
|
+
version: number;
|
|
658
|
+
/** Parent ID for hierarchical content */
|
|
659
|
+
parentId?: string | null;
|
|
660
|
+
/** Content locale this payload is reported in */
|
|
661
|
+
locale: string;
|
|
662
|
+
/** Publication state of `locale`; absent when that locale has no content of its own. */
|
|
663
|
+
localeStatus?: 'draft' | 'published' | 'archived';
|
|
664
|
+
/** Whether `locale` has unpublished changes of its own. */
|
|
665
|
+
localeHasDraft?: boolean;
|
|
666
|
+
/** Every locale with unpublished changes, including shared-field drafts. */
|
|
667
|
+
draftLocales?: string[];
|
|
668
|
+
/** Whether the shared (non-localized) fields have an unpublished overlay. */
|
|
669
|
+
hasDraft?: boolean;
|
|
670
|
+
/** Creation timestamp */
|
|
671
|
+
createdAt: Date;
|
|
672
|
+
/** Last update timestamp */
|
|
673
|
+
updatedAt: Date;
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Infer the TypeScript type from a content type definition
|
|
677
|
+
*
|
|
678
|
+
* This extracts all field IDs from the definition and creates a type
|
|
679
|
+
* with those fields as optional properties. Field names will autocomplete
|
|
680
|
+
* in SDK methods like where(), select(), etc.
|
|
681
|
+
*
|
|
682
|
+
* Note: Field values are typed as `unknown`. For full value type inference,
|
|
683
|
+
* use the codegen tool to generate proper types.
|
|
684
|
+
*
|
|
685
|
+
* @example
|
|
686
|
+
* const product = defineContentType('product', {
|
|
687
|
+
* displayName: 'Product',
|
|
688
|
+
* fields: [
|
|
689
|
+
* fields.shortText('title'),
|
|
690
|
+
* fields.currency('price'),
|
|
691
|
+
* ]
|
|
692
|
+
* })
|
|
693
|
+
*
|
|
694
|
+
* type Product = InferContentType<typeof product>
|
|
695
|
+
* // { title?: unknown; price?: unknown; _metadata: EntryMetadata }
|
|
696
|
+
*/
|
|
697
|
+
type InferContentType<T extends AnyContentTypeDefinition> = {
|
|
698
|
+
[K in ExtractFieldIds<T> & string]?: unknown;
|
|
699
|
+
} & {
|
|
700
|
+
_metadata: EntryMetadata;
|
|
701
|
+
};
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* Singleton content type definition matching @relyio/schema
|
|
705
|
+
*
|
|
706
|
+
* In RelyIO, singletons are just content types with a special flag.
|
|
707
|
+
* They share the same structure as regular content types.
|
|
708
|
+
*
|
|
709
|
+
* Uses advanced TypeScript generics to preserve literal field IDs through
|
|
710
|
+
* the type system, enabling full autocomplete in SDK methods.
|
|
711
|
+
*/
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* Type alias for a fieldset with any fields.
|
|
715
|
+
*/
|
|
716
|
+
type AnyFieldset$1 = Fieldset<any>;
|
|
717
|
+
/**
|
|
718
|
+
* Singleton content type definition - preserves field types for inference
|
|
719
|
+
*/
|
|
720
|
+
interface SingletonContentTypeDefinition<TFields extends readonly AnyFieldDefinition[] = readonly AnyFieldDefinition[], TFieldsets extends readonly AnyFieldset$1[] = readonly AnyFieldset$1[]> {
|
|
721
|
+
readonly _tag: 'singletonContentType';
|
|
722
|
+
readonly name: string;
|
|
723
|
+
readonly displayName: string;
|
|
724
|
+
readonly displayNamePlural?: string;
|
|
725
|
+
readonly description?: string;
|
|
726
|
+
/** AI configuration: generation guidance + entry intelligence */
|
|
727
|
+
readonly ai?: AIConfig;
|
|
728
|
+
/** Field ID to use as entry display title */
|
|
729
|
+
readonly displayField?: string;
|
|
730
|
+
readonly hierarchical: false;
|
|
731
|
+
readonly accessTags?: string[];
|
|
732
|
+
readonly fields?: TFields;
|
|
733
|
+
readonly fieldsets?: TFieldsets;
|
|
734
|
+
}
|
|
735
|
+
/**
|
|
736
|
+
* Define a singleton content type
|
|
737
|
+
*
|
|
738
|
+
* Singletons are single-instance content types like homepage, site settings, etc.
|
|
739
|
+
* They use the same field structure as regular content types.
|
|
740
|
+
*
|
|
741
|
+
* The generic type parameters preserve the literal field IDs through the type
|
|
742
|
+
* system, enabling autocomplete in SDK methods.
|
|
743
|
+
*
|
|
744
|
+
* @example
|
|
745
|
+
* const homepage = defineSingletonContentType('homepage', {
|
|
746
|
+
* displayName: 'Homepage',
|
|
747
|
+
* fields: [
|
|
748
|
+
* fields.shortText('heroTitle', { config: { required: true } }),
|
|
749
|
+
* fields.image('heroImage'),
|
|
750
|
+
* ]
|
|
751
|
+
* })
|
|
752
|
+
*/
|
|
753
|
+
declare function defineSingletonContentType<TFields extends readonly AnyFieldDefinition[], _TFieldsets extends readonly Fieldset<AnyFieldDefinition[]>[]>(name: string, config: ContentTypeConfigWithFields<TFields>): SingletonContentTypeDefinition<TFields, readonly []>;
|
|
754
|
+
declare function defineSingletonContentType<_TFields extends readonly AnyFieldDefinition[], TFieldsets extends readonly Fieldset<AnyFieldDefinition[]>[]>(name: string, config: ContentTypeConfigWithFieldsets<TFieldsets>): SingletonContentTypeDefinition<readonly [], TFieldsets>;
|
|
755
|
+
declare const defineSingleton: typeof defineSingletonContentType;
|
|
756
|
+
/**
|
|
757
|
+
* Singleton metadata
|
|
758
|
+
*/
|
|
759
|
+
interface SingletonMetadata {
|
|
760
|
+
/** Singleton key identifier */
|
|
761
|
+
key: string;
|
|
762
|
+
/** Singleton type identifier */
|
|
763
|
+
singletonType: string;
|
|
764
|
+
/** Content version */
|
|
765
|
+
version: number;
|
|
766
|
+
/** Content locale */
|
|
767
|
+
locale: string;
|
|
768
|
+
/** Creation timestamp */
|
|
769
|
+
createdAt: Date;
|
|
770
|
+
/** Last update timestamp */
|
|
771
|
+
updatedAt: Date;
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Type alias for any singleton content type definition.
|
|
775
|
+
*/
|
|
776
|
+
type AnySingletonContentTypeDefinition = SingletonContentTypeDefinition<any, any>;
|
|
777
|
+
/**
|
|
778
|
+
* Extract field IDs from a singleton content type definition
|
|
779
|
+
*/
|
|
780
|
+
type ExtractSingletonFieldIds<T extends AnySingletonContentTypeDefinition> = NonNullable<T['fields']> extends (infer F)[] ? F extends AnyFieldDefinition ? F['id'] : ExtractFromSingletonFieldsets<T> : ExtractFromSingletonFieldsets<T>;
|
|
781
|
+
type ExtractFromSingletonFieldsets<T extends AnySingletonContentTypeDefinition> = NonNullable<T['fieldsets']> extends (infer FS)[] ? FS extends Fieldset<infer Fields> ? Fields extends AnyFieldDefinition[] ? Fields[number]['id'] : never : never : never;
|
|
782
|
+
/**
|
|
783
|
+
* Infer the TypeScript type from a singleton definition
|
|
784
|
+
*/
|
|
785
|
+
type InferSingletonContentType<T extends AnySingletonContentTypeDefinition> = {
|
|
786
|
+
[K in ExtractSingletonFieldIds<T> & string]?: unknown;
|
|
787
|
+
} & {
|
|
788
|
+
_metadata: SingletonMetadata;
|
|
789
|
+
};
|
|
790
|
+
type InferSingleton<T extends AnySingletonContentTypeDefinition> = InferSingletonContentType<T>;
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* Component definition matching @relyio/schema ComponentSchema
|
|
794
|
+
*
|
|
795
|
+
* Components are reusable field groups that can be embedded in content types.
|
|
796
|
+
*/
|
|
797
|
+
|
|
798
|
+
interface ComponentReusabilityMetadata {
|
|
799
|
+
/** Minimum number of usages to be considered reusable */
|
|
800
|
+
minUsageCount?: number;
|
|
801
|
+
/** Maximum complexity score */
|
|
802
|
+
maxComplexity?: number;
|
|
803
|
+
/** Recommended usage contexts */
|
|
804
|
+
recommendedUsage?: string[];
|
|
805
|
+
}
|
|
806
|
+
interface ComponentValidationMetadata {
|
|
807
|
+
/** Whether nesting of components is allowed */
|
|
808
|
+
allowNesting?: boolean;
|
|
809
|
+
/** Maximum nesting depth */
|
|
810
|
+
maxNestingDepth?: number;
|
|
811
|
+
/** How to resolve field ID conflicts */
|
|
812
|
+
conflictResolution?: 'error' | 'component-wins' | 'field-wins' | 'prefix';
|
|
813
|
+
}
|
|
814
|
+
interface ComponentMetadata {
|
|
815
|
+
reusability?: ComponentReusabilityMetadata;
|
|
816
|
+
validation?: ComponentValidationMetadata;
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Component configuration
|
|
820
|
+
*/
|
|
821
|
+
interface ComponentConfig {
|
|
822
|
+
/** Display name shown in the UI */
|
|
823
|
+
displayName?: string;
|
|
824
|
+
/** Description of the component */
|
|
825
|
+
description?: string;
|
|
826
|
+
/** AI configuration for content generation and review */
|
|
827
|
+
ai?: AIConfig;
|
|
828
|
+
/** Whether this component is deprecated */
|
|
829
|
+
deprecated?: boolean;
|
|
830
|
+
/** Component fields */
|
|
831
|
+
fields: FieldDefinition[];
|
|
832
|
+
/** Component metadata for validation and reusability */
|
|
833
|
+
metadata?: ComponentMetadata;
|
|
834
|
+
}
|
|
835
|
+
/**
|
|
836
|
+
* Component definition
|
|
837
|
+
*/
|
|
838
|
+
interface ComponentDefinition {
|
|
839
|
+
readonly _tag: 'component';
|
|
840
|
+
readonly name: string;
|
|
841
|
+
readonly displayName?: string;
|
|
842
|
+
readonly description?: string;
|
|
843
|
+
/** AI configuration for content generation and review */
|
|
844
|
+
readonly ai?: AIConfig;
|
|
845
|
+
readonly deprecated: boolean;
|
|
846
|
+
readonly fields: FieldDefinition[];
|
|
847
|
+
readonly metadata?: ComponentMetadata;
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Define a reusable component (field group)
|
|
851
|
+
*
|
|
852
|
+
* @example
|
|
853
|
+
* const seoComponent = defineComponent('seoMetadata', {
|
|
854
|
+
* displayName: 'SEO Metadata',
|
|
855
|
+
* description: 'Common SEO fields for all content types',
|
|
856
|
+
* fields: [
|
|
857
|
+
* fields.shortText('metaTitle', {
|
|
858
|
+
* config: { maxLength: 60 },
|
|
859
|
+
* ui: { displayName: 'Meta Title' }
|
|
860
|
+
* }),
|
|
861
|
+
* fields.longText('metaDescription', {
|
|
862
|
+
* config: { maxLength: 160 },
|
|
863
|
+
* ui: { displayName: 'Meta Description' }
|
|
864
|
+
* }),
|
|
865
|
+
* fields.image('ogImage', {
|
|
866
|
+
* ui: { displayName: 'Open Graph Image' }
|
|
867
|
+
* }),
|
|
868
|
+
* ]
|
|
869
|
+
* })
|
|
870
|
+
*
|
|
871
|
+
* // Use in a content type:
|
|
872
|
+
* const product = defineContentType('product', {
|
|
873
|
+
* displayName: 'Product',
|
|
874
|
+
* fields: [
|
|
875
|
+
* fields.shortText('title', { config: { required: true } }),
|
|
876
|
+
* fields.component('seo', 'seoMetadata'), // Reference the component
|
|
877
|
+
* ]
|
|
878
|
+
* })
|
|
879
|
+
*/
|
|
880
|
+
declare function defineComponent(name: string, config: ComponentConfig): ComponentDefinition;
|
|
881
|
+
|
|
882
|
+
/**
|
|
883
|
+
* Settings group definition matching @relyio/schema SettingsGroupSchema
|
|
884
|
+
*
|
|
885
|
+
* Settings groups are for project-level configuration that doesn't fit
|
|
886
|
+
* into content types (e.g., API keys, feature flags, integrations).
|
|
887
|
+
*
|
|
888
|
+
* Uses advanced TypeScript generics to preserve literal field IDs through
|
|
889
|
+
* the type system, enabling full autocomplete in SDK methods.
|
|
890
|
+
*/
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* Settings group configuration - generic to preserve field types
|
|
894
|
+
*/
|
|
895
|
+
interface SettingsGroupConfig<TFields extends readonly AnyFieldDefinition[] = readonly AnyFieldDefinition[]> {
|
|
896
|
+
/** Display name shown in the UI */
|
|
897
|
+
displayName: string;
|
|
898
|
+
/** Description of the settings group */
|
|
899
|
+
description?: string;
|
|
900
|
+
/** AI configuration for content generation and review */
|
|
901
|
+
ai?: AIConfig;
|
|
902
|
+
/** Access tags for role-based access control */
|
|
903
|
+
accessTags?: string[];
|
|
904
|
+
/** Settings fields - preserves literal types */
|
|
905
|
+
fields: TFields;
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* Settings group definition - preserves field types for inference
|
|
909
|
+
*/
|
|
910
|
+
interface SettingsGroupDefinition<TFields extends readonly AnyFieldDefinition[] = readonly AnyFieldDefinition[]> {
|
|
911
|
+
readonly _tag: 'settingsGroup';
|
|
912
|
+
readonly name: string;
|
|
913
|
+
readonly displayName: string;
|
|
914
|
+
readonly description?: string;
|
|
915
|
+
/** AI configuration for content generation and review */
|
|
916
|
+
readonly ai?: AIConfig;
|
|
917
|
+
readonly accessTags?: string[];
|
|
918
|
+
readonly fields: TFields;
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* Define a settings group
|
|
922
|
+
*
|
|
923
|
+
* The generic type parameter preserves the literal field IDs through the type
|
|
924
|
+
* system, enabling autocomplete in SDK methods.
|
|
925
|
+
*
|
|
926
|
+
* @example
|
|
927
|
+
* const integrations = defineSettingsGroup('integrations', {
|
|
928
|
+
* displayName: 'Integrations',
|
|
929
|
+
* description: 'Third-party service integrations',
|
|
930
|
+
* fields: [
|
|
931
|
+
* fields.shortText('stripeApiKey', {
|
|
932
|
+
* config: { required: true },
|
|
933
|
+
* ui: { displayName: 'Stripe API Key' }
|
|
934
|
+
* }),
|
|
935
|
+
* fields.shortText('sendgridApiKey', {
|
|
936
|
+
* ui: { displayName: 'SendGrid API Key' }
|
|
937
|
+
* }),
|
|
938
|
+
* fields.boolean('enableAnalytics', {
|
|
939
|
+
* config: { defaultValue: true },
|
|
940
|
+
* ui: { displayName: 'Enable Analytics' }
|
|
941
|
+
* }),
|
|
942
|
+
* ]
|
|
943
|
+
* })
|
|
944
|
+
*/
|
|
945
|
+
declare function defineSettingsGroup<TFields extends readonly AnyFieldDefinition[]>(name: string, config: SettingsGroupConfig<TFields>): SettingsGroupDefinition<TFields>;
|
|
946
|
+
/**
|
|
947
|
+
* Type alias for any settings group definition.
|
|
948
|
+
*/
|
|
949
|
+
type AnySettingsGroupDefinition = SettingsGroupDefinition<any>;
|
|
950
|
+
/**
|
|
951
|
+
* Extract field IDs from a settings group definition
|
|
952
|
+
*/
|
|
953
|
+
type ExtractSettingsFieldIds<T extends AnySettingsGroupDefinition> = T['fields'] extends readonly AnyFieldDefinition[] ? T['fields'][number]['id'] : never;
|
|
954
|
+
/**
|
|
955
|
+
* Settings group metadata
|
|
956
|
+
*/
|
|
957
|
+
interface SettingsGroupMetadata {
|
|
958
|
+
/** Settings group key identifier */
|
|
959
|
+
key: string;
|
|
960
|
+
/** Settings group type identifier */
|
|
961
|
+
groupType: string;
|
|
962
|
+
/** Content version */
|
|
963
|
+
version: number;
|
|
964
|
+
/** Creation timestamp */
|
|
965
|
+
createdAt: Date;
|
|
966
|
+
/** Last update timestamp */
|
|
967
|
+
updatedAt: Date;
|
|
968
|
+
}
|
|
969
|
+
/**
|
|
970
|
+
* Infer the TypeScript type from a settings group definition
|
|
971
|
+
*/
|
|
972
|
+
type InferSettingsGroup<T extends AnySettingsGroupDefinition> = {
|
|
973
|
+
[K in ExtractSettingsFieldIds<T> & string]?: unknown;
|
|
974
|
+
} & {
|
|
975
|
+
_metadata: SettingsGroupMetadata;
|
|
976
|
+
};
|
|
977
|
+
|
|
978
|
+
/**
|
|
979
|
+
* Asset type definition matching @relyio/schema AssetTypeSchema
|
|
980
|
+
*
|
|
981
|
+
* Asset types are first-class entries (entryType: 'asset') that pair a binary
|
|
982
|
+
* pipeline family (declared via exactly one kind key: `image`, `video`, or
|
|
983
|
+
* `file`) with user-defined metadata fields that reuse the standard field
|
|
984
|
+
* system — including fieldsets, workflow, access tags, and AI config.
|
|
985
|
+
*
|
|
986
|
+
* The kind config blocks are strongly typed below (mirroring the zod-inferred
|
|
987
|
+
* `@relyio/schema` types), so authoring asset types in TypeScript gets full
|
|
988
|
+
* autocomplete. The authoritative validation still lives in @relyio/schema's
|
|
989
|
+
* `AssetTypesValidator` and runs on deploy.
|
|
990
|
+
*/
|
|
991
|
+
|
|
992
|
+
/** Resize fit modes supported by the Cloudflare Images binding. */
|
|
993
|
+
type ImageFitMode = 'cover' | 'contain' | 'fill' | 'inside' | 'outside';
|
|
994
|
+
/** Output formats the Cloudflare Images binding can produce (`heic` is input-only). */
|
|
995
|
+
type ImageOutputFormat = 'avif' | 'webp' | 'jpeg' | 'png';
|
|
996
|
+
/** Shared image transform props (CF Images vocabulary). */
|
|
997
|
+
interface ImageTransform {
|
|
998
|
+
width?: number;
|
|
999
|
+
height?: number;
|
|
1000
|
+
fit?: ImageFitMode;
|
|
1001
|
+
format?: ImageOutputFormat;
|
|
1002
|
+
quality?: number;
|
|
1003
|
+
}
|
|
1004
|
+
/** Upload gate for the `image` kind (rejects bad files at the door). */
|
|
1005
|
+
interface ImageUploadConfig {
|
|
1006
|
+
allowedMimeTypes?: string[];
|
|
1007
|
+
maxFileSize?: number;
|
|
1008
|
+
minWidth?: number;
|
|
1009
|
+
maxWidth?: number;
|
|
1010
|
+
minHeight?: number;
|
|
1011
|
+
maxHeight?: number;
|
|
1012
|
+
/** `width:height`, e.g. `16:9`. */
|
|
1013
|
+
aspectRatio?: string;
|
|
1014
|
+
}
|
|
1015
|
+
/** Upload gate for the `video` kind. */
|
|
1016
|
+
interface VideoUploadConfig {
|
|
1017
|
+
allowedMimeTypes?: string[];
|
|
1018
|
+
maxFileSize?: number;
|
|
1019
|
+
maxDuration?: number;
|
|
1020
|
+
minWidth?: number;
|
|
1021
|
+
maxWidth?: number;
|
|
1022
|
+
minHeight?: number;
|
|
1023
|
+
maxHeight?: number;
|
|
1024
|
+
}
|
|
1025
|
+
/** Upload gate for the `file` kind (MIME + size only in v1). */
|
|
1026
|
+
interface FileUploadConfig {
|
|
1027
|
+
allowedMimeTypes?: string[];
|
|
1028
|
+
maxFileSize?: number;
|
|
1029
|
+
}
|
|
1030
|
+
/** Delivery rendition preset (max 20 per asset type), applied on the fly by the gateway. */
|
|
1031
|
+
interface VariantDefinition extends ImageTransform {
|
|
1032
|
+
/** Variant id; must start with a letter (codegen emits the `*Variant` union from these). */
|
|
1033
|
+
id: string;
|
|
1034
|
+
}
|
|
1035
|
+
/**
|
|
1036
|
+
* Ingest normalization of the canonical stored original (image v1 only).
|
|
1037
|
+
* `true` expands to the platform default on deploy.
|
|
1038
|
+
*/
|
|
1039
|
+
type ImageSourceConfig = boolean | (ImageTransform & {
|
|
1040
|
+
stripMetadata?: boolean;
|
|
1041
|
+
});
|
|
1042
|
+
/** EXIF retention policy for the `image` kind (plan 15). */
|
|
1043
|
+
interface ImageExifConfig {
|
|
1044
|
+
/** Retain GPS in `extracted.exif` (default strips it for privacy). */
|
|
1045
|
+
keepGps?: boolean;
|
|
1046
|
+
}
|
|
1047
|
+
/** Image kind config (`upload`, `source`, `variants`, `localization`, `exif`). */
|
|
1048
|
+
interface ImageKindConfig {
|
|
1049
|
+
upload?: ImageUploadConfig;
|
|
1050
|
+
source?: ImageSourceConfig;
|
|
1051
|
+
/** Max 20 variants per asset type. */
|
|
1052
|
+
variants?: VariantDefinition[];
|
|
1053
|
+
localization?: LocalizationConfig;
|
|
1054
|
+
exif?: ImageExifConfig;
|
|
1055
|
+
}
|
|
1056
|
+
/** Poster/thumbnail strategy for the `video` kind. */
|
|
1057
|
+
interface VideoPosterConfig {
|
|
1058
|
+
/** 0.0–1.0 → Stream thumbnailTimestampPct. */
|
|
1059
|
+
defaultTimestampPct?: number;
|
|
1060
|
+
/** Enable an animated preview (gif/webp). */
|
|
1061
|
+
animated?: boolean;
|
|
1062
|
+
}
|
|
1063
|
+
/** Subtitle track strategy for the `video` kind. */
|
|
1064
|
+
interface VideoCaptionsConfig {
|
|
1065
|
+
enabled?: boolean;
|
|
1066
|
+
requiredLocales?: string[];
|
|
1067
|
+
/** Stream AI transcription when no track is uploaded. */
|
|
1068
|
+
autoGenerate?: boolean;
|
|
1069
|
+
}
|
|
1070
|
+
/** Downloadable-MP4 toggle for the `video` kind. */
|
|
1071
|
+
interface VideoDownloadConfig {
|
|
1072
|
+
enabled?: boolean;
|
|
1073
|
+
}
|
|
1074
|
+
/** Stream watermark profile for the `video` kind. */
|
|
1075
|
+
interface VideoWatermarkConfig {
|
|
1076
|
+
enabled?: boolean;
|
|
1077
|
+
/** Account-level Stream watermark profile uid. */
|
|
1078
|
+
profileId?: string;
|
|
1079
|
+
}
|
|
1080
|
+
/**
|
|
1081
|
+
* Video kind config (`upload`, `poster`, `captions`, `download`, `watermark`,
|
|
1082
|
+
* `localization`). Stream auto-generates the ABR ladder — there is intentionally
|
|
1083
|
+
* NO `variants` and NO `encoding` block.
|
|
1084
|
+
*/
|
|
1085
|
+
interface VideoKindConfig {
|
|
1086
|
+
upload?: VideoUploadConfig;
|
|
1087
|
+
poster?: VideoPosterConfig;
|
|
1088
|
+
captions?: VideoCaptionsConfig;
|
|
1089
|
+
download?: VideoDownloadConfig;
|
|
1090
|
+
watermark?: VideoWatermarkConfig;
|
|
1091
|
+
localization?: LocalizationConfig;
|
|
1092
|
+
}
|
|
1093
|
+
/** Malware scan config for the `file` kind (plan 19). */
|
|
1094
|
+
interface FileScanConfig {
|
|
1095
|
+
enabled?: boolean;
|
|
1096
|
+
blockUntilClean?: boolean;
|
|
1097
|
+
}
|
|
1098
|
+
/** File kind config (`upload`, `localization`, `scan`, `extractText`). */
|
|
1099
|
+
interface FileKindConfig {
|
|
1100
|
+
upload?: FileUploadConfig;
|
|
1101
|
+
localization?: LocalizationConfig;
|
|
1102
|
+
/** Malware scan (plan 19). */
|
|
1103
|
+
scan?: FileScanConfig;
|
|
1104
|
+
/** Extract searchable text + metadata for PDFs (plan 15). */
|
|
1105
|
+
extractText?: boolean;
|
|
1106
|
+
}
|
|
1107
|
+
interface AssetTypeBaseConfig {
|
|
1108
|
+
/** Display name shown in the UI */
|
|
1109
|
+
displayName: string;
|
|
1110
|
+
/** Plural display name (e.g., "Product Photos" for "Product Photo") */
|
|
1111
|
+
displayNamePlural?: string;
|
|
1112
|
+
/** Description of the asset type */
|
|
1113
|
+
description?: string;
|
|
1114
|
+
/**
|
|
1115
|
+
* AI configuration. `ai.instructions` is an optional global brief; per-field
|
|
1116
|
+
* `ai.instructions` describe individual fields. `ai.autoGenerate` (image
|
|
1117
|
+
* kind, v1) is the master switch: when true, the derived analysis agent runs
|
|
1118
|
+
* after upload and fills every field that declares `ai.instructions`, applied
|
|
1119
|
+
* as a review proposal.
|
|
1120
|
+
*/
|
|
1121
|
+
ai?: AssetAIConfig;
|
|
1122
|
+
/** Field ID to use as the asset display title */
|
|
1123
|
+
displayField?: string;
|
|
1124
|
+
/** Access tags for role-based access control */
|
|
1125
|
+
accessTags?: string[];
|
|
1126
|
+
/** Workflow configuration for this asset type */
|
|
1127
|
+
workflow?: ContentTypeWorkflowConfig;
|
|
1128
|
+
/** Image pipeline config — mutually exclusive with `video`/`file` */
|
|
1129
|
+
image?: ImageKindConfig;
|
|
1130
|
+
/** Video pipeline config — mutually exclusive with `image`/`file` */
|
|
1131
|
+
video?: VideoKindConfig;
|
|
1132
|
+
/** File pipeline config — mutually exclusive with `image`/`video` */
|
|
1133
|
+
file?: FileKindConfig;
|
|
1134
|
+
}
|
|
1135
|
+
/**
|
|
1136
|
+
* Type alias for a fieldset with any fields.
|
|
1137
|
+
*/
|
|
1138
|
+
type AnyFieldset = Fieldset<any>;
|
|
1139
|
+
/** Asset type configuration using direct fields. */
|
|
1140
|
+
interface AssetTypeConfigWithFields<TFields extends readonly AnyFieldDefinition[] = readonly AnyFieldDefinition[]> extends AssetTypeBaseConfig {
|
|
1141
|
+
/** Direct field definitions - preserves literal types */
|
|
1142
|
+
fields: TFields;
|
|
1143
|
+
/** Cannot have fieldsets when using fields */
|
|
1144
|
+
fieldsets?: never;
|
|
1145
|
+
}
|
|
1146
|
+
/** Asset type configuration using fieldsets. */
|
|
1147
|
+
interface AssetTypeConfigWithFieldsets<TFieldsets extends readonly AnyFieldset[] = readonly AnyFieldset[]> extends AssetTypeBaseConfig {
|
|
1148
|
+
/** Field organization via fieldsets - preserves literal types */
|
|
1149
|
+
fieldsets: TFieldsets;
|
|
1150
|
+
/** Cannot have direct fields when using fieldsets */
|
|
1151
|
+
fields?: never;
|
|
1152
|
+
}
|
|
1153
|
+
/** Asset type configuration (either fields OR fieldsets). */
|
|
1154
|
+
type AssetTypeConfig<TFields extends readonly AnyFieldDefinition[] = readonly AnyFieldDefinition[], TFieldsets extends readonly AnyFieldset[] = readonly AnyFieldset[]> = AssetTypeConfigWithFields<TFields> | AssetTypeConfigWithFieldsets<TFieldsets>;
|
|
1155
|
+
/** Asset type definition - preserves field types for inference. */
|
|
1156
|
+
interface AssetTypeDefinition<TFields extends readonly AnyFieldDefinition[] = readonly AnyFieldDefinition[], TFieldsets extends readonly AnyFieldset[] = readonly AnyFieldset[]> {
|
|
1157
|
+
readonly _tag: 'assetType';
|
|
1158
|
+
readonly name: string;
|
|
1159
|
+
readonly displayName: string;
|
|
1160
|
+
readonly displayNamePlural?: string;
|
|
1161
|
+
readonly description?: string;
|
|
1162
|
+
readonly ai?: AssetAIConfig;
|
|
1163
|
+
readonly displayField?: string;
|
|
1164
|
+
readonly accessTags?: string[];
|
|
1165
|
+
readonly workflow?: ContentTypeWorkflowConfig;
|
|
1166
|
+
readonly image?: ImageKindConfig;
|
|
1167
|
+
readonly video?: VideoKindConfig;
|
|
1168
|
+
readonly file?: FileKindConfig;
|
|
1169
|
+
readonly fields?: TFields;
|
|
1170
|
+
readonly fieldsets?: TFieldsets;
|
|
1171
|
+
}
|
|
1172
|
+
/**
|
|
1173
|
+
* Define an asset type.
|
|
1174
|
+
*
|
|
1175
|
+
* Exactly one kind key (`image`, `video`, or `file`) must be supplied. The
|
|
1176
|
+
* generic type parameters preserve literal field IDs for inference, mirroring
|
|
1177
|
+
* `defineContentType`.
|
|
1178
|
+
*
|
|
1179
|
+
* @example
|
|
1180
|
+
* const productPhoto = defineAssetType('productPhoto', {
|
|
1181
|
+
* displayName: 'Product Photo',
|
|
1182
|
+
* image: {
|
|
1183
|
+
* upload: { allowedMimeTypes: ['image/jpeg', 'image/png', 'image/webp'], maxFileSize: 10485760 },
|
|
1184
|
+
* variants: [{ id: 'thumb', width: 200, height: 200, fit: 'cover', format: 'webp' }],
|
|
1185
|
+
* },
|
|
1186
|
+
* fields: [
|
|
1187
|
+
* fields.shortText('altText', { ui: { displayName: 'Alt Text' } }),
|
|
1188
|
+
* ],
|
|
1189
|
+
* })
|
|
1190
|
+
*/
|
|
1191
|
+
declare function defineAssetType<TFields extends readonly AnyFieldDefinition[], _TFieldsets extends readonly Fieldset<AnyFieldDefinition[]>[]>(name: string, config: AssetTypeConfigWithFields<TFields>): AssetTypeDefinition<TFields, readonly []>;
|
|
1192
|
+
declare function defineAssetType<_TFields extends readonly AnyFieldDefinition[], TFieldsets extends readonly Fieldset<AnyFieldDefinition[]>[]>(name: string, config: AssetTypeConfigWithFieldsets<TFieldsets>): AssetTypeDefinition<readonly [], TFieldsets>;
|
|
1193
|
+
/**
|
|
1194
|
+
* Type alias for any asset type definition.
|
|
1195
|
+
*/
|
|
1196
|
+
type AnyAssetTypeDefinition = AssetTypeDefinition<any, any>;
|
|
1197
|
+
type ExtractAssetFieldIds<T extends AnyAssetTypeDefinition> = NonNullable<T['fields']> extends (infer F)[] ? F extends AnyFieldDefinition ? F['id'] : ExtractFromAssetFieldsets<T> : ExtractFromAssetFieldsets<T>;
|
|
1198
|
+
type ExtractFromAssetFieldsets<T extends AnyAssetTypeDefinition> = NonNullable<T['fieldsets']> extends (infer FS)[] ? FS extends Fieldset<infer Fields> ? Fields extends AnyFieldDefinition[] ? Fields[number]['id'] : never : never : never;
|
|
1199
|
+
/**
|
|
1200
|
+
* Infer the TypeScript type from an asset type definition.
|
|
1201
|
+
*
|
|
1202
|
+
* Mirrors {@link InferContentType}: produces the (optional) metadata field shape
|
|
1203
|
+
* plus `_metadata`, so it is assignable to `BaseContent` and can parametrize
|
|
1204
|
+
* `AssetClient<T>`. The runtime `file`/`urls` blocks are layered on by the
|
|
1205
|
+
* client's `AssetEntryResponse<T>` return type, not here, to keep the schema
|
|
1206
|
+
* layer free of any dependency on the client layer.
|
|
1207
|
+
*/
|
|
1208
|
+
type InferAssetType<T extends AnyAssetTypeDefinition> = {
|
|
1209
|
+
[K in ExtractAssetFieldIds<T> & string]?: unknown;
|
|
1210
|
+
} & {
|
|
1211
|
+
_metadata: EntryMetadata;
|
|
1212
|
+
};
|
|
1213
|
+
|
|
1214
|
+
/**
|
|
1215
|
+
* Query definition matching @relyio/schema QueryDefinitionSchema
|
|
1216
|
+
*
|
|
1217
|
+
* Queries define predefined API endpoints with filtering, sorting, and caching.
|
|
1218
|
+
*/
|
|
1219
|
+
type WhereOperator = {
|
|
1220
|
+
gte?: string | number;
|
|
1221
|
+
lte?: string | number;
|
|
1222
|
+
gt?: string | number;
|
|
1223
|
+
lt?: string | number;
|
|
1224
|
+
ne?: string | number | boolean;
|
|
1225
|
+
in?: (string | number | boolean)[];
|
|
1226
|
+
nin?: (string | number | boolean)[];
|
|
1227
|
+
contains?: string;
|
|
1228
|
+
startsWith?: string;
|
|
1229
|
+
endsWith?: string;
|
|
1230
|
+
exists?: boolean;
|
|
1231
|
+
notExists?: boolean;
|
|
1232
|
+
};
|
|
1233
|
+
type WhereValue = string | number | boolean | (string | number | boolean)[] | WhereOperator;
|
|
1234
|
+
type WhereCondition = Record<string, WhereValue>;
|
|
1235
|
+
type SortDirection = 'asc' | 'desc';
|
|
1236
|
+
type SortCondition = Record<string, SortDirection> | Record<string, SortDirection>[];
|
|
1237
|
+
type IncludeRelationship = {
|
|
1238
|
+
relationship: string;
|
|
1239
|
+
where?: WhereCondition;
|
|
1240
|
+
aggregate?: 'count' | 'sum' | 'avg' | 'min' | 'max';
|
|
1241
|
+
alias?: string;
|
|
1242
|
+
};
|
|
1243
|
+
type IncludePath = {
|
|
1244
|
+
path: string;
|
|
1245
|
+
fields?: string[];
|
|
1246
|
+
include?: (string | IncludePath)[];
|
|
1247
|
+
where?: WhereCondition;
|
|
1248
|
+
};
|
|
1249
|
+
type IncludeDefinition = string | string[] | (string | IncludeRelationship | IncludePath)[];
|
|
1250
|
+
type SelectMapping = Record<string, string>;
|
|
1251
|
+
type FilterOperator = {
|
|
1252
|
+
gte?: string;
|
|
1253
|
+
lte?: string;
|
|
1254
|
+
gt?: string;
|
|
1255
|
+
lt?: string;
|
|
1256
|
+
in?: string;
|
|
1257
|
+
nin?: string;
|
|
1258
|
+
};
|
|
1259
|
+
type FilterDefinition = Record<string, string | FilterOperator>;
|
|
1260
|
+
type CachePolicyObject = {
|
|
1261
|
+
policy: 'public' | 'private' | 'no-cache';
|
|
1262
|
+
ttl?: number;
|
|
1263
|
+
staleWhileRevalidate?: number;
|
|
1264
|
+
tags?: string[];
|
|
1265
|
+
};
|
|
1266
|
+
type CachePolicy = string | CachePolicyObject;
|
|
1267
|
+
/**
|
|
1268
|
+
* Fetch block - retrieve content entries
|
|
1269
|
+
*/
|
|
1270
|
+
interface FetchBlock {
|
|
1271
|
+
/** Content type to fetch */
|
|
1272
|
+
contentType?: string;
|
|
1273
|
+
/** Singleton to fetch */
|
|
1274
|
+
singleton?: string;
|
|
1275
|
+
/** Filter conditions */
|
|
1276
|
+
where?: WhereCondition;
|
|
1277
|
+
/** Related content to include */
|
|
1278
|
+
include?: IncludeDefinition;
|
|
1279
|
+
/** Sort order */
|
|
1280
|
+
sort?: SortCondition;
|
|
1281
|
+
/** Maximum results */
|
|
1282
|
+
limit?: number;
|
|
1283
|
+
/** Results offset */
|
|
1284
|
+
offset?: number;
|
|
1285
|
+
}
|
|
1286
|
+
/**
|
|
1287
|
+
* Aggregate block - perform aggregations
|
|
1288
|
+
*/
|
|
1289
|
+
interface AggregateBlock {
|
|
1290
|
+
/** Source content type (required when not used with fetch) */
|
|
1291
|
+
source?: string;
|
|
1292
|
+
/** Filter conditions */
|
|
1293
|
+
where?: WhereCondition;
|
|
1294
|
+
/** Group by field(s) */
|
|
1295
|
+
by?: string | string[] | (string | {
|
|
1296
|
+
expression: string;
|
|
1297
|
+
as?: string;
|
|
1298
|
+
})[];
|
|
1299
|
+
/** Aggregation operations */
|
|
1300
|
+
aggregations?: Record<string, string>;
|
|
1301
|
+
/** Legacy: same as aggregations */
|
|
1302
|
+
metrics?: Record<string, string>;
|
|
1303
|
+
/** Having clause for filtering aggregations */
|
|
1304
|
+
having?: Record<string, string | number | boolean | WhereOperator>;
|
|
1305
|
+
/** Sort order */
|
|
1306
|
+
sort?: SortCondition;
|
|
1307
|
+
/** Maximum results */
|
|
1308
|
+
limit?: number;
|
|
1309
|
+
}
|
|
1310
|
+
/**
|
|
1311
|
+
* Search block - full-text and semantic search
|
|
1312
|
+
*/
|
|
1313
|
+
interface SearchBlock {
|
|
1314
|
+
/** Single content type */
|
|
1315
|
+
contentType?: string;
|
|
1316
|
+
/** Multiple content types or "*" for all */
|
|
1317
|
+
contentTypes?: string | string[] | '*';
|
|
1318
|
+
/** Search query string */
|
|
1319
|
+
query: string;
|
|
1320
|
+
/** Fields to search in */
|
|
1321
|
+
searchFields?: string[];
|
|
1322
|
+
/** Legacy search type */
|
|
1323
|
+
searchType?: 'plainto' | 'phraseto' | 'websearch' | 'to_tsquery';
|
|
1324
|
+
/** Filter conditions */
|
|
1325
|
+
where?: WhereCondition;
|
|
1326
|
+
/** Field mapping for results */
|
|
1327
|
+
fields?: SelectMapping;
|
|
1328
|
+
/** Include relevance score */
|
|
1329
|
+
includeRank?: boolean;
|
|
1330
|
+
/** Include score breakdown */
|
|
1331
|
+
explain?: boolean;
|
|
1332
|
+
/** Highlight matching terms */
|
|
1333
|
+
highlight?: boolean | {
|
|
1334
|
+
field?: string;
|
|
1335
|
+
maxWords?: number;
|
|
1336
|
+
minWords?: number;
|
|
1337
|
+
shortWord?: number;
|
|
1338
|
+
};
|
|
1339
|
+
/** Sort order */
|
|
1340
|
+
sort?: SortCondition;
|
|
1341
|
+
/** Maximum results */
|
|
1342
|
+
limit?: number;
|
|
1343
|
+
/** Results offset */
|
|
1344
|
+
offset?: number;
|
|
1345
|
+
}
|
|
1346
|
+
/**
|
|
1347
|
+
* Similar block - find similar content via vector search
|
|
1348
|
+
*/
|
|
1349
|
+
interface SimilarBlock {
|
|
1350
|
+
/** Single content type */
|
|
1351
|
+
contentType?: string;
|
|
1352
|
+
/** Multiple content types or "*" for all */
|
|
1353
|
+
contentTypes?: string | string[] | '*';
|
|
1354
|
+
/** Source entry UID to find similar content for */
|
|
1355
|
+
source: string;
|
|
1356
|
+
/** Filter conditions */
|
|
1357
|
+
where?: WhereCondition;
|
|
1358
|
+
/** Field mapping for results */
|
|
1359
|
+
fields?: SelectMapping;
|
|
1360
|
+
/** Maximum results */
|
|
1361
|
+
limit?: number;
|
|
1362
|
+
}
|
|
1363
|
+
/**
|
|
1364
|
+
* Include sub-queries for additional data
|
|
1365
|
+
*/
|
|
1366
|
+
interface IncludeSubQuery {
|
|
1367
|
+
source: string;
|
|
1368
|
+
where?: WhereCondition;
|
|
1369
|
+
sort?: SortCondition;
|
|
1370
|
+
limit?: number;
|
|
1371
|
+
select?: SelectMapping;
|
|
1372
|
+
}
|
|
1373
|
+
type IncludeSubQueries = Record<string, IncludeSubQuery>;
|
|
1374
|
+
/**
|
|
1375
|
+
* Query definition configuration
|
|
1376
|
+
*/
|
|
1377
|
+
interface QueryConfig {
|
|
1378
|
+
/** API endpoint path (required, e.g., /api/featured-products) */
|
|
1379
|
+
endpoint: string;
|
|
1380
|
+
/** Query description */
|
|
1381
|
+
description?: string;
|
|
1382
|
+
/** Fetch block for retrieving entries */
|
|
1383
|
+
fetch?: FetchBlock;
|
|
1384
|
+
/** Aggregate block for aggregations */
|
|
1385
|
+
aggregate?: AggregateBlock;
|
|
1386
|
+
/** Search block for full-text/semantic search */
|
|
1387
|
+
search?: SearchBlock;
|
|
1388
|
+
/** Similar block for vector similarity search */
|
|
1389
|
+
similar?: SimilarBlock;
|
|
1390
|
+
/** Include sub-queries */
|
|
1391
|
+
include?: IncludeSubQueries;
|
|
1392
|
+
/** Dynamic filter definitions */
|
|
1393
|
+
filters?: FilterDefinition;
|
|
1394
|
+
/** Field selection/mapping */
|
|
1395
|
+
select?: SelectMapping;
|
|
1396
|
+
/** Cache policy */
|
|
1397
|
+
cache?: CachePolicy;
|
|
1398
|
+
}
|
|
1399
|
+
/**
|
|
1400
|
+
* Query definition
|
|
1401
|
+
*/
|
|
1402
|
+
interface QueryDefinition {
|
|
1403
|
+
readonly _tag: 'query';
|
|
1404
|
+
readonly name: string;
|
|
1405
|
+
readonly endpoint: string;
|
|
1406
|
+
readonly description?: string;
|
|
1407
|
+
readonly fetch?: FetchBlock;
|
|
1408
|
+
readonly aggregate?: AggregateBlock;
|
|
1409
|
+
readonly search?: SearchBlock;
|
|
1410
|
+
readonly similar?: SimilarBlock;
|
|
1411
|
+
readonly include?: IncludeSubQueries;
|
|
1412
|
+
readonly filters?: FilterDefinition;
|
|
1413
|
+
readonly select?: SelectMapping;
|
|
1414
|
+
readonly cache?: CachePolicy;
|
|
1415
|
+
}
|
|
1416
|
+
/**
|
|
1417
|
+
* Define a predefined query
|
|
1418
|
+
*
|
|
1419
|
+
* @example
|
|
1420
|
+
* const featuredProducts = defineQuery('featuredProducts', {
|
|
1421
|
+
* endpoint: '/api/featured-products',
|
|
1422
|
+
* description: 'Get featured products for homepage',
|
|
1423
|
+
* fetch: {
|
|
1424
|
+
* contentType: 'product',
|
|
1425
|
+
* where: {
|
|
1426
|
+
* status: 'active',
|
|
1427
|
+
* featured: true,
|
|
1428
|
+
* },
|
|
1429
|
+
* include: ['brand', 'categories'],
|
|
1430
|
+
* sort: { publishedAt: 'desc' },
|
|
1431
|
+
* limit: 10,
|
|
1432
|
+
* },
|
|
1433
|
+
* cache: {
|
|
1434
|
+
* policy: 'public',
|
|
1435
|
+
* ttl: 300,
|
|
1436
|
+
* staleWhileRevalidate: 60,
|
|
1437
|
+
* }
|
|
1438
|
+
* })
|
|
1439
|
+
*
|
|
1440
|
+
* @example
|
|
1441
|
+
* const searchProducts = defineQuery('searchProducts', {
|
|
1442
|
+
* endpoint: '/api/search',
|
|
1443
|
+
* description: 'Search products with semantic understanding',
|
|
1444
|
+
* search: {
|
|
1445
|
+
* contentType: 'product',
|
|
1446
|
+
* query: '${q}',
|
|
1447
|
+
* where: { status: 'active' },
|
|
1448
|
+
* highlight: true,
|
|
1449
|
+
* limit: 20,
|
|
1450
|
+
* },
|
|
1451
|
+
* filters: {
|
|
1452
|
+
* 'price.base': { gte: '${minPrice?0}', lte: '${maxPrice?}' },
|
|
1453
|
+
* category: '${categoryId?}',
|
|
1454
|
+
* },
|
|
1455
|
+
* cache: 'public 60s',
|
|
1456
|
+
* })
|
|
1457
|
+
*
|
|
1458
|
+
* @example
|
|
1459
|
+
* const productStats = defineQuery('productStats', {
|
|
1460
|
+
* endpoint: '/api/products/stats',
|
|
1461
|
+
* description: 'Get product statistics by category',
|
|
1462
|
+
* aggregate: {
|
|
1463
|
+
* source: 'product',
|
|
1464
|
+
* where: { status: 'active' },
|
|
1465
|
+
* by: ['category'],
|
|
1466
|
+
* aggregations: {
|
|
1467
|
+
* totalProducts: 'id.count',
|
|
1468
|
+
* avgPrice: 'price.base.avg',
|
|
1469
|
+
* minPrice: 'price.base.min',
|
|
1470
|
+
* maxPrice: 'price.base.max',
|
|
1471
|
+
* },
|
|
1472
|
+
* sort: { totalProducts: 'desc' },
|
|
1473
|
+
* },
|
|
1474
|
+
* cache: 'public 300s',
|
|
1475
|
+
* })
|
|
1476
|
+
*/
|
|
1477
|
+
declare function defineQuery(name: string, config: QueryConfig): QueryDefinition;
|
|
1478
|
+
/**
|
|
1479
|
+
* Infer basic response type from a query definition
|
|
1480
|
+
* Note: For accurate types, use the codegen tool
|
|
1481
|
+
*/
|
|
1482
|
+
type InferQueryResponse<_T extends QueryDefinition> = unknown[];
|
|
1483
|
+
/**
|
|
1484
|
+
* Infer parameters from a query definition
|
|
1485
|
+
* Note: For accurate types, use the codegen tool
|
|
1486
|
+
*/
|
|
1487
|
+
type InferQueryParams<_T extends QueryDefinition> = Record<string, unknown>;
|
|
1488
|
+
|
|
1489
|
+
/**
|
|
1490
|
+
* Locale definition for multi-language support
|
|
1491
|
+
*
|
|
1492
|
+
* Locales define the languages and regions available for content
|
|
1493
|
+
* within your RelyIO project. Each locale can have:
|
|
1494
|
+
* - A fallback chain for missing content
|
|
1495
|
+
* - RTL text direction support
|
|
1496
|
+
* - Active/inactive status for gradual rollouts
|
|
1497
|
+
*
|
|
1498
|
+
* @example
|
|
1499
|
+
* import { defineLocale, defineSchema } from '@relyio/sdk/schema'
|
|
1500
|
+
*
|
|
1501
|
+
* const enUS = defineLocale('en-US', {
|
|
1502
|
+
* displayName: 'English (US)',
|
|
1503
|
+
* default: true,
|
|
1504
|
+
* })
|
|
1505
|
+
*
|
|
1506
|
+
* const esES = defineLocale('es-ES', {
|
|
1507
|
+
* displayName: 'Spanish (Spain)',
|
|
1508
|
+
* fallback: ['en-US'],
|
|
1509
|
+
* })
|
|
1510
|
+
*
|
|
1511
|
+
* const arSA = defineLocale('ar-SA', {
|
|
1512
|
+
* displayName: 'Arabic (Saudi Arabia)',
|
|
1513
|
+
* direction: 'rtl',
|
|
1514
|
+
* fallback: ['en-US'],
|
|
1515
|
+
* })
|
|
1516
|
+
*
|
|
1517
|
+
* export const schema = defineSchema({
|
|
1518
|
+
* locales: [enUS, esES, arSA],
|
|
1519
|
+
* contentTypes: { ... },
|
|
1520
|
+
* })
|
|
1521
|
+
*/
|
|
1522
|
+
/**
|
|
1523
|
+
* Text direction for RTL language support
|
|
1524
|
+
*/
|
|
1525
|
+
type TextDirection = 'ltr' | 'rtl';
|
|
1526
|
+
/**
|
|
1527
|
+
* Options for defining a locale
|
|
1528
|
+
*/
|
|
1529
|
+
interface LocaleOptions {
|
|
1530
|
+
/** Human-readable name shown in the Studio UI */
|
|
1531
|
+
displayName: string;
|
|
1532
|
+
/**
|
|
1533
|
+
* Marks the default locale (exactly one required per schema)
|
|
1534
|
+
* The default locale serves as the ultimate fallback for all other locales
|
|
1535
|
+
*/
|
|
1536
|
+
default?: boolean;
|
|
1537
|
+
/**
|
|
1538
|
+
* Ordered fallback chain when content is missing in this locale
|
|
1539
|
+
* Locales are tried in order until content is found
|
|
1540
|
+
*
|
|
1541
|
+
* @example
|
|
1542
|
+
* // Spanish Mexico falls back to Spain Spanish, then US English
|
|
1543
|
+
* fallback: ['es-ES', 'en-US']
|
|
1544
|
+
*/
|
|
1545
|
+
fallback?: string[];
|
|
1546
|
+
/**
|
|
1547
|
+
* Text direction for RTL languages like Arabic, Hebrew
|
|
1548
|
+
* @default 'ltr'
|
|
1549
|
+
*/
|
|
1550
|
+
direction?: TextDirection;
|
|
1551
|
+
/**
|
|
1552
|
+
* Enable/disable locale without removing translations
|
|
1553
|
+
* Useful for:
|
|
1554
|
+
* - Testing new locales before enabling them
|
|
1555
|
+
* - Temporarily disabling locales for compliance review
|
|
1556
|
+
* - Gradual market rollouts
|
|
1557
|
+
*
|
|
1558
|
+
* Note: Inactive locales can still serve as fallback targets
|
|
1559
|
+
* @default true
|
|
1560
|
+
*/
|
|
1561
|
+
active?: boolean;
|
|
1562
|
+
}
|
|
1563
|
+
/**
|
|
1564
|
+
* Locale definition with type tag for SDK type inference
|
|
1565
|
+
*/
|
|
1566
|
+
interface LocaleDefinition {
|
|
1567
|
+
readonly _tag: 'locale';
|
|
1568
|
+
readonly code: string;
|
|
1569
|
+
readonly displayName: string;
|
|
1570
|
+
readonly default?: boolean;
|
|
1571
|
+
readonly fallback?: readonly string[];
|
|
1572
|
+
readonly direction?: TextDirection;
|
|
1573
|
+
readonly active?: boolean;
|
|
1574
|
+
}
|
|
1575
|
+
/**
|
|
1576
|
+
* Define a locale for multi-language support
|
|
1577
|
+
*
|
|
1578
|
+
* Creates a locale definition that can be included in your schema.
|
|
1579
|
+
* Locales control:
|
|
1580
|
+
* - What languages/regions are available for content
|
|
1581
|
+
* - Fallback behavior when content is missing
|
|
1582
|
+
* - Text direction for RTL languages
|
|
1583
|
+
*
|
|
1584
|
+
* @param code BCP 47 locale code (e.g., 'en-US', 'fr-FR', 'ar-SA')
|
|
1585
|
+
* @param options Locale configuration
|
|
1586
|
+
* @returns Locale definition for use in defineSchema()
|
|
1587
|
+
*
|
|
1588
|
+
* @example
|
|
1589
|
+
* // Basic locale
|
|
1590
|
+
* const enUS = defineLocale('en-US', {
|
|
1591
|
+
* displayName: 'English (US)',
|
|
1592
|
+
* default: true,
|
|
1593
|
+
* })
|
|
1594
|
+
*
|
|
1595
|
+
* @example
|
|
1596
|
+
* // Locale with fallback chain
|
|
1597
|
+
* const esMX = defineLocale('es-MX', {
|
|
1598
|
+
* displayName: 'Spanish (Mexico)',
|
|
1599
|
+
* fallback: ['es-ES', 'en-US'],
|
|
1600
|
+
* })
|
|
1601
|
+
*
|
|
1602
|
+
* @example
|
|
1603
|
+
* // RTL language
|
|
1604
|
+
* const arSA = defineLocale('ar-SA', {
|
|
1605
|
+
* displayName: 'Arabic (Saudi Arabia)',
|
|
1606
|
+
* direction: 'rtl',
|
|
1607
|
+
* fallback: ['en-US'],
|
|
1608
|
+
* })
|
|
1609
|
+
*
|
|
1610
|
+
* @example
|
|
1611
|
+
* // Inactive locale for testing
|
|
1612
|
+
* const jaJP = defineLocale('ja-JP', {
|
|
1613
|
+
* displayName: 'Japanese',
|
|
1614
|
+
* fallback: ['en-US'],
|
|
1615
|
+
* active: false, // Hidden from Studio UI, but translations preserved
|
|
1616
|
+
* })
|
|
1617
|
+
*/
|
|
1618
|
+
declare function defineLocale(code: string, options: LocaleOptions): LocaleDefinition;
|
|
1619
|
+
/**
|
|
1620
|
+
* Type guard to check if a value is a LocaleDefinition
|
|
1621
|
+
*/
|
|
1622
|
+
declare function isLocaleDefinition(value: unknown): value is LocaleDefinition;
|
|
1623
|
+
/**
|
|
1624
|
+
* Extract locale codes from an array of locale definitions
|
|
1625
|
+
*/
|
|
1626
|
+
declare function getLocaleCodes(locales: readonly LocaleDefinition[]): string[];
|
|
1627
|
+
/**
|
|
1628
|
+
* Find the default locale from an array of locale definitions
|
|
1629
|
+
*/
|
|
1630
|
+
declare function findDefaultLocale(locales: readonly LocaleDefinition[]): LocaleDefinition | undefined;
|
|
1631
|
+
/**
|
|
1632
|
+
* Get active locales (excludes inactive ones)
|
|
1633
|
+
*/
|
|
1634
|
+
declare function getActiveLocales(locales: readonly LocaleDefinition[]): LocaleDefinition[];
|
|
1635
|
+
/**
|
|
1636
|
+
* Build the complete fallback chain for a locale, resolving transitive fallbacks
|
|
1637
|
+
*
|
|
1638
|
+
* @param localeCode The locale to build the fallback chain for
|
|
1639
|
+
* @param locales All defined locales
|
|
1640
|
+
* @param maxDepth Maximum depth to prevent infinite loops (default: 10)
|
|
1641
|
+
* @returns Ordered array of locale codes to try as fallbacks
|
|
1642
|
+
*
|
|
1643
|
+
* @example
|
|
1644
|
+
* // Given: es-MX → es-ES → en-US (default)
|
|
1645
|
+
* buildFallbackChain('es-MX', locales)
|
|
1646
|
+
* // Returns: ['es-ES', 'en-US']
|
|
1647
|
+
*/
|
|
1648
|
+
declare function buildFallbackChain(localeCode: string, locales: readonly LocaleDefinition[], maxDepth?: number): string[];
|
|
1649
|
+
|
|
1650
|
+
/**
|
|
1651
|
+
* Role definition for fine-grained access control
|
|
1652
|
+
*
|
|
1653
|
+
* Roles define what users can do within a project. They can:
|
|
1654
|
+
* - Inherit from built-in roles (admin, editor, viewer)
|
|
1655
|
+
* - Compose from other roles using 'includes'
|
|
1656
|
+
* - Define granular permissions by access tags
|
|
1657
|
+
* - Set field visibility (hidden/readonly)
|
|
1658
|
+
*/
|
|
1659
|
+
/**
|
|
1660
|
+
* Built-in roles that are always available
|
|
1661
|
+
*/
|
|
1662
|
+
declare const BUILT_IN_ROLES: readonly ["admin", "editor", "viewer"];
|
|
1663
|
+
type BuiltInRole = (typeof BUILT_IN_ROLES)[number];
|
|
1664
|
+
/**
|
|
1665
|
+
* All available content actions
|
|
1666
|
+
*/
|
|
1667
|
+
declare const ROLE_ACTIONS: readonly ["create", "read", "update", "delete", "publish", "unpublish", "duplicate", "comment", "approveElevated"];
|
|
1668
|
+
type RoleAction = (typeof ROLE_ACTIONS)[number];
|
|
1669
|
+
/**
|
|
1670
|
+
* Default actions for each built-in role
|
|
1671
|
+
*/
|
|
1672
|
+
declare const BUILT_IN_ROLE_ACTIONS: Record<BuiltInRole, readonly RoleAction[]>;
|
|
1673
|
+
/**
|
|
1674
|
+
* Resource permission rule - defines what actions are allowed for specific tags
|
|
1675
|
+
*/
|
|
1676
|
+
interface ResourcePermission {
|
|
1677
|
+
/** Access tags this permission applies to */
|
|
1678
|
+
tags: string[];
|
|
1679
|
+
/** Actions allowed for resources with these tags */
|
|
1680
|
+
actions: RoleAction[];
|
|
1681
|
+
}
|
|
1682
|
+
/**
|
|
1683
|
+
* Field visibility permissions
|
|
1684
|
+
*/
|
|
1685
|
+
interface FieldVisibility {
|
|
1686
|
+
/** Fields that are hidden from this role (cannot see) */
|
|
1687
|
+
hidden?: string[];
|
|
1688
|
+
/** Fields that are readonly for this role (can see but not edit) */
|
|
1689
|
+
readonly?: string[];
|
|
1690
|
+
}
|
|
1691
|
+
/**
|
|
1692
|
+
* Role configuration
|
|
1693
|
+
*/
|
|
1694
|
+
interface RoleConfig {
|
|
1695
|
+
/** Human-readable name shown in Studio */
|
|
1696
|
+
displayName: string;
|
|
1697
|
+
/** Optional description for administrators */
|
|
1698
|
+
description?: string;
|
|
1699
|
+
/** Inherit from a built-in role (admin, editor, viewer) */
|
|
1700
|
+
baseRole?: BuiltInRole;
|
|
1701
|
+
/** Compose from other roles (built-in or custom) */
|
|
1702
|
+
includes?: string[];
|
|
1703
|
+
/** Resource permission rules */
|
|
1704
|
+
permissions?: ResourcePermission[];
|
|
1705
|
+
/** Field visibility settings */
|
|
1706
|
+
fields?: FieldVisibility;
|
|
1707
|
+
}
|
|
1708
|
+
/**
|
|
1709
|
+
* Complete role definition
|
|
1710
|
+
*/
|
|
1711
|
+
interface RoleDefinition {
|
|
1712
|
+
readonly _tag: 'role';
|
|
1713
|
+
readonly id: string;
|
|
1714
|
+
readonly displayName: string;
|
|
1715
|
+
readonly description?: string;
|
|
1716
|
+
readonly baseRole?: BuiltInRole;
|
|
1717
|
+
readonly includes?: string[];
|
|
1718
|
+
readonly permissions?: ResourcePermission[];
|
|
1719
|
+
readonly fields?: FieldVisibility;
|
|
1720
|
+
}
|
|
1721
|
+
/**
|
|
1722
|
+
* Define a custom role
|
|
1723
|
+
*
|
|
1724
|
+
* @example
|
|
1725
|
+
* // Inherit from built-in role
|
|
1726
|
+
* const blogEditor = defineRole('blog-editor', {
|
|
1727
|
+
* displayName: 'Blog Editor',
|
|
1728
|
+
* baseRole: 'editor',
|
|
1729
|
+
* permissions: [
|
|
1730
|
+
* { tags: ['blog'], actions: ['create', 'read', 'update', 'publish'] }
|
|
1731
|
+
* ]
|
|
1732
|
+
* })
|
|
1733
|
+
*
|
|
1734
|
+
* @example
|
|
1735
|
+
* // Compose from other roles
|
|
1736
|
+
* const seniorEditor = defineRole('senior-editor', {
|
|
1737
|
+
* displayName: 'Senior Editor',
|
|
1738
|
+
* includes: ['blog-editor', 'news-editor'],
|
|
1739
|
+
* permissions: [
|
|
1740
|
+
* { tags: ['featured'], actions: ['publish', 'unpublish'] }
|
|
1741
|
+
* ]
|
|
1742
|
+
* })
|
|
1743
|
+
*
|
|
1744
|
+
* @example
|
|
1745
|
+
* // Full permissions control
|
|
1746
|
+
* const moderator = defineRole('moderator', {
|
|
1747
|
+
* displayName: 'Content Moderator',
|
|
1748
|
+
* permissions: [
|
|
1749
|
+
* { tags: ['comments'], actions: ['read', 'delete'] }
|
|
1750
|
+
* ],
|
|
1751
|
+
* fields: {
|
|
1752
|
+
* hidden: ['internalNotes'],
|
|
1753
|
+
* readonly: ['authorId']
|
|
1754
|
+
* }
|
|
1755
|
+
* })
|
|
1756
|
+
*/
|
|
1757
|
+
declare function defineRole(id: string, config: RoleConfig): RoleDefinition;
|
|
1758
|
+
/**
|
|
1759
|
+
* Check if a value is a role definition
|
|
1760
|
+
*/
|
|
1761
|
+
declare function isRoleDefinition(value: unknown): value is RoleDefinition;
|
|
1762
|
+
/**
|
|
1763
|
+
* Check if a role ID is a built-in role
|
|
1764
|
+
*/
|
|
1765
|
+
declare function isBuiltInRole(roleId: string): roleId is BuiltInRole;
|
|
1766
|
+
/**
|
|
1767
|
+
* Get the default actions for a built-in role
|
|
1768
|
+
*/
|
|
1769
|
+
declare function getBuiltInRoleActions(roleId: BuiltInRole): readonly RoleAction[];
|
|
1770
|
+
|
|
1771
|
+
/**
|
|
1772
|
+
* View definitions for SDK schema
|
|
1773
|
+
*
|
|
1774
|
+
* Views define pre-configured entry list configurations with filters,
|
|
1775
|
+
* columns, and metadata display settings.
|
|
1776
|
+
*/
|
|
1777
|
+
/**
|
|
1778
|
+
* View scope defines which content types a view applies to.
|
|
1779
|
+
*
|
|
1780
|
+
* When using `contentTypes` (plural) or `all`, the view displays entries
|
|
1781
|
+
* from multiple content types. In this case:
|
|
1782
|
+
*
|
|
1783
|
+
* - Columns/fields may only exist on some content types
|
|
1784
|
+
* - For entries where a field doesn't exist, the UI displays "—"
|
|
1785
|
+
* - System fields (id, status, createdAt, updatedAt) exist on all entries
|
|
1786
|
+
* - Filters on non-existent fields are skipped for that entry type
|
|
1787
|
+
*
|
|
1788
|
+
* Example display:
|
|
1789
|
+
* | Content Type | title | author | productCode |
|
|
1790
|
+
* |--------------|-------|--------|-------------|
|
|
1791
|
+
* | post | ✓ | ✓ | — |
|
|
1792
|
+
* | product | ✓ | — | ✓ |
|
|
1793
|
+
*/
|
|
1794
|
+
/**
|
|
1795
|
+
* Scope for a single content type
|
|
1796
|
+
*/
|
|
1797
|
+
interface ContentTypeScopeConfig {
|
|
1798
|
+
type: 'contentType';
|
|
1799
|
+
contentType: string;
|
|
1800
|
+
}
|
|
1801
|
+
/**
|
|
1802
|
+
* Scope for multiple content types
|
|
1803
|
+
*
|
|
1804
|
+
* Fields not present on all content types will show "—" in the UI
|
|
1805
|
+
*/
|
|
1806
|
+
interface ContentTypesScopeConfig {
|
|
1807
|
+
type: 'contentTypes';
|
|
1808
|
+
contentTypes: string[];
|
|
1809
|
+
}
|
|
1810
|
+
/**
|
|
1811
|
+
* Scope for an entry type (content, singleton, settings, asset)
|
|
1812
|
+
*/
|
|
1813
|
+
interface EntryTypeScopeConfig {
|
|
1814
|
+
type: 'entryType';
|
|
1815
|
+
entryType: 'content' | 'singleton' | 'settings' | 'asset';
|
|
1816
|
+
}
|
|
1817
|
+
/**
|
|
1818
|
+
* Scope for all content
|
|
1819
|
+
*
|
|
1820
|
+
* Fields not present on all content types will show "—" in the UI
|
|
1821
|
+
*/
|
|
1822
|
+
interface AllScopeConfig {
|
|
1823
|
+
type: 'all';
|
|
1824
|
+
}
|
|
1825
|
+
/**
|
|
1826
|
+
* View scope options
|
|
1827
|
+
*/
|
|
1828
|
+
type ViewScopeConfig = ContentTypeScopeConfig | ContentTypesScopeConfig | EntryTypeScopeConfig | AllScopeConfig;
|
|
1829
|
+
/**
|
|
1830
|
+
* Filter operators supported in view filters.
|
|
1831
|
+
*
|
|
1832
|
+
* Reverse-reference operators (`linksTo` / `doesNotLinkTo` / `hasAnyLink` /
|
|
1833
|
+
* `hasNoLinks`) are intentionally absent: they were advertised here without a
|
|
1834
|
+
* compiler, and a runtime no-op that silently drops a filter is worse than
|
|
1835
|
+
* refusing the type. `@relyio/entry-reads`' `declareOperatorNames` makes naming
|
|
1836
|
+
* an operator with no catalog `compile` a build failure. Follow-up: reverse-
|
|
1837
|
+
* reference operators with entry-reads P5/P6 expansion.
|
|
1838
|
+
*/
|
|
1839
|
+
type ViewFilterOperator = 'is' | 'isNot' | 'contains' | 'doesNotContain' | 'startsWith' | 'endsWith' | 'isEmpty' | 'isNotEmpty' | 'equals' | 'notEquals' | 'greaterThan' | 'greaterThanOrEqual' | 'lessThan' | 'lessThanOrEqual' | 'between' | 'isBefore' | 'isAfter' | 'isOnOrBefore' | 'isOnOrAfter' | 'inTheLast' | 'inTheNext' | 'today' | 'yesterday' | 'tomorrow' | 'thisWeek' | 'lastWeek' | 'thisMonth' | 'lastMonth' | 'isTrue' | 'isFalse' | 'isAnyOf' | 'isNoneOf' | 'includes' | 'includesAll' | 'includesAny' | 'excludes';
|
|
1840
|
+
/**
|
|
1841
|
+
* Simple filter condition
|
|
1842
|
+
*/
|
|
1843
|
+
interface ViewFilterCondition {
|
|
1844
|
+
/**
|
|
1845
|
+
* Field ID to filter on
|
|
1846
|
+
*/
|
|
1847
|
+
field: string;
|
|
1848
|
+
/**
|
|
1849
|
+
* Filter operator
|
|
1850
|
+
*/
|
|
1851
|
+
operator: ViewFilterOperator;
|
|
1852
|
+
/**
|
|
1853
|
+
* Filter value (optional for some operators like isEmpty)
|
|
1854
|
+
*/
|
|
1855
|
+
value?: unknown;
|
|
1856
|
+
}
|
|
1857
|
+
/**
|
|
1858
|
+
* Grouped filter conditions with AND/OR logic
|
|
1859
|
+
*/
|
|
1860
|
+
interface ViewFilterGroup {
|
|
1861
|
+
/**
|
|
1862
|
+
* Logical operator to combine conditions
|
|
1863
|
+
*/
|
|
1864
|
+
operator: 'and' | 'or';
|
|
1865
|
+
/**
|
|
1866
|
+
* Array of conditions in this group
|
|
1867
|
+
*/
|
|
1868
|
+
conditions: ViewFilterCondition[];
|
|
1869
|
+
}
|
|
1870
|
+
/**
|
|
1871
|
+
* Filter configuration can be simple conditions or groups
|
|
1872
|
+
*/
|
|
1873
|
+
type ViewFilter = ViewFilterCondition | ViewFilterGroup;
|
|
1874
|
+
/**
|
|
1875
|
+
* View definition configuration
|
|
1876
|
+
*/
|
|
1877
|
+
interface ViewConfig {
|
|
1878
|
+
/**
|
|
1879
|
+
* Display name for the view
|
|
1880
|
+
*/
|
|
1881
|
+
name: string;
|
|
1882
|
+
/**
|
|
1883
|
+
* URL-friendly slug for the view (optional, auto-generated from id if not provided)
|
|
1884
|
+
* Used in Studio URLs like /studio/views/:slug
|
|
1885
|
+
*/
|
|
1886
|
+
slug?: string;
|
|
1887
|
+
/**
|
|
1888
|
+
* Optional description for the view
|
|
1889
|
+
*/
|
|
1890
|
+
description?: string;
|
|
1891
|
+
/**
|
|
1892
|
+
* Icon (emoji or icon name) for the view
|
|
1893
|
+
*/
|
|
1894
|
+
icon?: string;
|
|
1895
|
+
/**
|
|
1896
|
+
* Color for the view in the sidebar
|
|
1897
|
+
*/
|
|
1898
|
+
color?: string;
|
|
1899
|
+
/**
|
|
1900
|
+
* View scope - what content types this view applies to
|
|
1901
|
+
*/
|
|
1902
|
+
scope: ViewScopeConfig;
|
|
1903
|
+
/**
|
|
1904
|
+
* Filter conditions (optional)
|
|
1905
|
+
* Simple array of conditions will be combined with AND
|
|
1906
|
+
*/
|
|
1907
|
+
filters?: ViewFilter[];
|
|
1908
|
+
/**
|
|
1909
|
+
* Column field IDs to display (optional)
|
|
1910
|
+
* If not specified, uses default columns
|
|
1911
|
+
*/
|
|
1912
|
+
columns?: string[];
|
|
1913
|
+
/**
|
|
1914
|
+
* Metadata field IDs to show under title (max 3)
|
|
1915
|
+
*/
|
|
1916
|
+
metadataFields?: string[];
|
|
1917
|
+
/**
|
|
1918
|
+
* Default sort configuration (optional)
|
|
1919
|
+
*/
|
|
1920
|
+
sort?: {
|
|
1921
|
+
field: string;
|
|
1922
|
+
direction: 'asc' | 'desc';
|
|
1923
|
+
};
|
|
1924
|
+
/**
|
|
1925
|
+
* Sort order in the sidebar (lower = higher priority)
|
|
1926
|
+
*/
|
|
1927
|
+
sortOrder?: number;
|
|
1928
|
+
}
|
|
1929
|
+
/**
|
|
1930
|
+
* Complete view definition with ID
|
|
1931
|
+
*/
|
|
1932
|
+
interface ViewDefinition extends ViewConfig {
|
|
1933
|
+
/**
|
|
1934
|
+
* Internal tag for type discrimination
|
|
1935
|
+
*/
|
|
1936
|
+
readonly _tag: 'view';
|
|
1937
|
+
/**
|
|
1938
|
+
* Unique view ID (must start with a letter)
|
|
1939
|
+
*/
|
|
1940
|
+
readonly id: string;
|
|
1941
|
+
/**
|
|
1942
|
+
* URL-friendly slug for the view
|
|
1943
|
+
* Auto-generated from id if not provided in config
|
|
1944
|
+
*/
|
|
1945
|
+
readonly slug: string;
|
|
1946
|
+
}
|
|
1947
|
+
declare function defineView(id: string, config: ViewConfig): ViewDefinition;
|
|
1948
|
+
/**
|
|
1949
|
+
* Convert a view definition to JSON format for the schema
|
|
1950
|
+
*/
|
|
1951
|
+
declare function viewToJSON(view: ViewDefinition): object;
|
|
1952
|
+
|
|
1953
|
+
/**
|
|
1954
|
+
* Schema definition matching @relyio/schema SchemaDefinitionSchema
|
|
1955
|
+
*
|
|
1956
|
+
* Note: `version` is NOT user-defined - it's auto-generated by the backend.
|
|
1957
|
+
*/
|
|
1958
|
+
|
|
1959
|
+
/**
|
|
1960
|
+
* Schema configuration
|
|
1961
|
+
*
|
|
1962
|
+
* Matches the SchemaDefinitionSchema from @relyio/schema:
|
|
1963
|
+
* - locales: Optional array of locale definitions for multi-language support
|
|
1964
|
+
* - contentTypes: Required record of content type definitions
|
|
1965
|
+
* - components: Required record of component definitions (can be empty {})
|
|
1966
|
+
* - singletonContentTypes: Required record of singleton definitions (can be empty {})
|
|
1967
|
+
* - queries: Required record of query definitions (can be empty {})
|
|
1968
|
+
* - settingsGroups: Optional record of settings groups
|
|
1969
|
+
* - roles: Optional array of custom role definitions for access control
|
|
1970
|
+
* - workflow: Optional workflow configuration with approval stages
|
|
1971
|
+
*
|
|
1972
|
+
* Note: `version` is auto-generated by the backend, not user-defined!
|
|
1973
|
+
*/
|
|
1974
|
+
interface SchemaConfig {
|
|
1975
|
+
/** Locale definitions for multi-language support (optional) */
|
|
1976
|
+
locales?: LocaleDefinition[];
|
|
1977
|
+
/** Content type definitions (required) */
|
|
1978
|
+
contentTypes: Record<string, ContentTypeDefinition>;
|
|
1979
|
+
/** Reusable component definitions (required, can be empty) */
|
|
1980
|
+
components?: Record<string, ComponentDefinition>;
|
|
1981
|
+
/** Singleton content type definitions (required, can be empty) */
|
|
1982
|
+
singletonContentTypes?: Record<string, SingletonContentTypeDefinition>;
|
|
1983
|
+
/** Predefined query definitions (required, can be empty) */
|
|
1984
|
+
queries?: Record<string, QueryDefinition>;
|
|
1985
|
+
/** Settings group definitions (optional) */
|
|
1986
|
+
settingsGroups?: Record<string, SettingsGroupDefinition>;
|
|
1987
|
+
/** Asset type definitions (optional) */
|
|
1988
|
+
assetTypes?: Record<string, AssetTypeDefinition>;
|
|
1989
|
+
/** Custom role definitions for fine-grained access control (optional) */
|
|
1990
|
+
roles?: RoleDefinition[];
|
|
1991
|
+
/** Global workflow configuration with approval stages (optional) */
|
|
1992
|
+
workflow?: WorkflowDefinition;
|
|
1993
|
+
/** View definitions for pre-configured entry list views (optional) */
|
|
1994
|
+
views?: ViewDefinition[];
|
|
1995
|
+
}
|
|
1996
|
+
/**
|
|
1997
|
+
* Complete schema definition - Generic version for type inference
|
|
1998
|
+
*/
|
|
1999
|
+
interface SchemaDefinition<TContentTypes extends Record<string, ContentTypeDefinition> = Record<string, ContentTypeDefinition>, TComponents extends Record<string, ComponentDefinition> = Record<string, ComponentDefinition>, TSingletons extends Record<string, SingletonContentTypeDefinition> = Record<string, SingletonContentTypeDefinition>, TQueries extends Record<string, QueryDefinition> = Record<string, QueryDefinition>, TSettings extends Record<string, SettingsGroupDefinition> = Record<string, SettingsGroupDefinition>, TLocales extends readonly LocaleDefinition[] = readonly LocaleDefinition[], TRoles extends readonly RoleDefinition[] = readonly RoleDefinition[], TWorkflow extends WorkflowDefinition | undefined = WorkflowDefinition | undefined, TViews extends readonly ViewDefinition[] = readonly ViewDefinition[], TAssets extends Record<string, AssetTypeDefinition> = Record<string, AssetTypeDefinition>> {
|
|
2000
|
+
readonly _tag: 'schema';
|
|
2001
|
+
readonly locales?: TLocales;
|
|
2002
|
+
readonly contentTypes: TContentTypes;
|
|
2003
|
+
readonly components: TComponents;
|
|
2004
|
+
readonly singletonContentTypes: TSingletons;
|
|
2005
|
+
readonly queries: TQueries;
|
|
2006
|
+
readonly settingsGroups?: TSettings;
|
|
2007
|
+
readonly assetTypes?: TAssets;
|
|
2008
|
+
readonly roles?: TRoles;
|
|
2009
|
+
readonly workflow?: TWorkflow;
|
|
2010
|
+
readonly views?: TViews;
|
|
2011
|
+
}
|
|
2012
|
+
/**
|
|
2013
|
+
* Typed schema config for type inference
|
|
2014
|
+
*/
|
|
2015
|
+
interface TypedSchemaConfig<TContentTypes extends Record<string, ContentTypeDefinition>, TComponents extends Record<string, ComponentDefinition>, TSingletons extends Record<string, SingletonContentTypeDefinition>, TQueries extends Record<string, QueryDefinition>, TSettings extends Record<string, SettingsGroupDefinition>, TLocales extends readonly LocaleDefinition[] = readonly LocaleDefinition[], TRoles extends readonly RoleDefinition[] = readonly RoleDefinition[], TWorkflow extends WorkflowDefinition | undefined = WorkflowDefinition | undefined, TViews extends readonly ViewDefinition[] = readonly ViewDefinition[], TAssets extends Record<string, AssetTypeDefinition> = Record<string, AssetTypeDefinition>> {
|
|
2016
|
+
locales?: TLocales;
|
|
2017
|
+
contentTypes: TContentTypes;
|
|
2018
|
+
components?: TComponents;
|
|
2019
|
+
singletonContentTypes?: TSingletons;
|
|
2020
|
+
queries?: TQueries;
|
|
2021
|
+
settingsGroups?: TSettings;
|
|
2022
|
+
assetTypes?: TAssets;
|
|
2023
|
+
roles?: TRoles;
|
|
2024
|
+
workflow?: TWorkflow;
|
|
2025
|
+
views?: TViews;
|
|
2026
|
+
}
|
|
2027
|
+
/**
|
|
2028
|
+
* Define a complete schema
|
|
2029
|
+
*
|
|
2030
|
+
* This creates a schema definition that can be:
|
|
2031
|
+
* 1. Deployed via the CLI
|
|
2032
|
+
* 2. Used for type inference in the SDK client
|
|
2033
|
+
*
|
|
2034
|
+
* @example
|
|
2035
|
+
* import { defineSchema, defineContentType, defineComponent, defineLocale, fields } from '@relyio/sdk/schema'
|
|
2036
|
+
*
|
|
2037
|
+
* const enUS = defineLocale('en-US', { displayName: 'English (US)', default: true })
|
|
2038
|
+
* const esES = defineLocale('es-ES', { displayName: 'Spanish', fallback: ['en-US'] })
|
|
2039
|
+
*
|
|
2040
|
+
* const seoComponent = defineComponent('seo', {
|
|
2041
|
+
* displayName: 'SEO Metadata',
|
|
2042
|
+
* fields: [
|
|
2043
|
+
* fields.shortText('metaTitle', { config: { maxLength: 60 } }),
|
|
2044
|
+
* fields.longText('metaDescription', { config: { maxLength: 160 } }),
|
|
2045
|
+
* ]
|
|
2046
|
+
* })
|
|
2047
|
+
*
|
|
2048
|
+
* const product = defineContentType('product', {
|
|
2049
|
+
* displayName: 'Product',
|
|
2050
|
+
* fields: [
|
|
2051
|
+
* fields.shortText('title', { config: { required: true }, localization: true }),
|
|
2052
|
+
* fields.currency('price', { config: { currencyCode: 'USD' } }),
|
|
2053
|
+
* fields.component('seo', 'seo'),
|
|
2054
|
+
* ]
|
|
2055
|
+
* })
|
|
2056
|
+
*
|
|
2057
|
+
* export const schema = defineSchema({
|
|
2058
|
+
* locales: [enUS, esES],
|
|
2059
|
+
* contentTypes: { product },
|
|
2060
|
+
* components: { seo: seoComponent },
|
|
2061
|
+
* })
|
|
2062
|
+
*/
|
|
2063
|
+
declare function defineSchema<TContentTypes extends Record<string, ContentTypeDefinition>, TComponents extends Record<string, ComponentDefinition> = Record<string, never>, TSingletons extends Record<string, SingletonContentTypeDefinition> = Record<string, never>, TQueries extends Record<string, QueryDefinition> = Record<string, never>, TSettings extends Record<string, SettingsGroupDefinition> = Record<string, never>, TLocales extends readonly LocaleDefinition[] = readonly LocaleDefinition[], TRoles extends readonly RoleDefinition[] = readonly RoleDefinition[], TWorkflow extends WorkflowDefinition | undefined = WorkflowDefinition | undefined, TViews extends readonly ViewDefinition[] = readonly ViewDefinition[], TAssets extends Record<string, AssetTypeDefinition> = Record<string, never>>(config: TypedSchemaConfig<TContentTypes, TComponents, TSingletons, TQueries, TSettings, TLocales, TRoles, TWorkflow, TViews, TAssets>): SchemaDefinition<TContentTypes, TComponents, TSingletons, TQueries, TSettings, TLocales, TRoles, TWorkflow, TViews, TAssets>;
|
|
2064
|
+
/**
|
|
2065
|
+
* Convert a schema definition to JSON format for the CLI
|
|
2066
|
+
*
|
|
2067
|
+
* This strips out the _tag properties and converts to the format
|
|
2068
|
+
* expected by the RelyIO backend.
|
|
2069
|
+
*/
|
|
2070
|
+
declare function schemaToJSON(schema: SchemaDefinition): object;
|
|
2071
|
+
/**
|
|
2072
|
+
* Type alias for any schema definition.
|
|
2073
|
+
* Uses `any` intentionally for type inference utilities that need to accept any schema.
|
|
2074
|
+
*/
|
|
2075
|
+
type AnySchemaDefinition = SchemaDefinition<any, any, any, any, any, any, any, any, any>;
|
|
2076
|
+
/**
|
|
2077
|
+
* Get content type names from a schema
|
|
2078
|
+
*/
|
|
2079
|
+
type SchemaContentTypeNames<T extends AnySchemaDefinition> = keyof T['contentTypes'] & string;
|
|
2080
|
+
/**
|
|
2081
|
+
* Get singleton names from a schema
|
|
2082
|
+
*/
|
|
2083
|
+
type SchemaSingletonNames<T extends AnySchemaDefinition> = keyof T['singletonContentTypes'] & string;
|
|
2084
|
+
/**
|
|
2085
|
+
* Get query names from a schema
|
|
2086
|
+
*/
|
|
2087
|
+
type SchemaQueryNames<T extends AnySchemaDefinition> = keyof T['queries'] & string;
|
|
2088
|
+
/**
|
|
2089
|
+
* Get settings group names from a schema
|
|
2090
|
+
*/
|
|
2091
|
+
type SchemaSettingsGroupNames<T extends AnySchemaDefinition> = T['settingsGroups'] extends Record<string, SettingsGroupDefinition> ? keyof T['settingsGroups'] & string : never;
|
|
2092
|
+
/**
|
|
2093
|
+
* Get asset type names from a schema
|
|
2094
|
+
*/
|
|
2095
|
+
type SchemaAssetTypeNames<T extends AnySchemaDefinition> = T['assetTypes'] extends Record<string, AssetTypeDefinition> ? keyof T['assetTypes'] & string : never;
|
|
2096
|
+
/**
|
|
2097
|
+
* Get locale codes from a schema
|
|
2098
|
+
*/
|
|
2099
|
+
type SchemaLocaleCodes<T extends AnySchemaDefinition> = T['locales'] extends readonly LocaleDefinition[] ? T['locales'][number]['code'] : never;
|
|
2100
|
+
|
|
2101
|
+
export { fieldset as $, type AIConfig as A, type BooleanConfig as B, type ComponentFieldType as C, type DecimalConfig as D, type EmailConfig as E, type FieldUIConfig as F, type SchemaQueryNames as G, type SchemaLocaleCodes as H, type IntegerConfig as I, type SchemaSettingsGroupNames as J, type SchemaAssetTypeNames as K, type LocalizationConfig as L, defineLocale as M, isLocaleDefinition as N, getLocaleCodes as O, findDefaultLocale as P, getActiveLocales as Q, type RichTextConfig as R, type ShortTextConfig as S, type TagsConfig as T, type UrlConfig as U, type ValidationRule as V, buildFallbackChain as W, type TextDirection as X, type LocaleOptions as Y, type LocaleDefinition as Z, defineContentType as _, type FieldAIConfig as a, isWorkflowDefinition as a$, type Fieldset as a0, type ContentTypeConfig as a1, type ContentTypeConfigWithFields as a2, type ContentTypeConfigWithFieldsets as a3, type ContentTypeDefinition as a4, type EntryMetadata as a5, type InferContentType as a6, defineSingletonContentType as a7, defineSingleton as a8, type SingletonContentTypeDefinition as a9, type ImageUploadConfig as aA, type ImageSourceConfig as aB, type ImageExifConfig as aC, type VariantDefinition as aD, type VideoUploadConfig as aE, type VideoPosterConfig as aF, type VideoCaptionsConfig as aG, type VideoDownloadConfig as aH, type VideoWatermarkConfig as aI, type FileUploadConfig as aJ, type FileScanConfig as aK, defineRole as aL, isRoleDefinition as aM, isBuiltInRole as aN, getBuiltInRoleActions as aO, BUILT_IN_ROLES as aP, ROLE_ACTIONS as aQ, BUILT_IN_ROLE_ACTIONS as aR, type BuiltInRole as aS, type RoleAction as aT, type ResourcePermission as aU, type FieldVisibility as aV, type RoleConfig as aW, type RoleDefinition as aX, defineWorkflow as aY, defineWorkflowStage as aZ, defineContentTypeWorkflow as a_, type SingletonMetadata as aa, type InferSingletonContentType as ab, type InferSingleton as ac, defineComponent as ad, type ComponentConfig as ae, type ComponentDefinition as af, type ComponentMetadata as ag, type ComponentReusabilityMetadata as ah, type ComponentValidationMetadata as ai, defineSettingsGroup as aj, type SettingsGroupConfig as ak, type SettingsGroupDefinition as al, type SettingsGroupMetadata as am, type InferSettingsGroup as an, defineAssetType as ao, type AssetTypeConfig as ap, type AssetTypeConfigWithFields as aq, type AssetTypeConfigWithFieldsets as ar, type AssetTypeDefinition as as, type InferAssetType as at, type ImageKindConfig as au, type VideoKindConfig as av, type FileKindConfig as aw, type ImageTransform as ax, type ImageFitMode as ay, type ImageOutputFormat as az, type FieldRule as b, isWorkflowStageDefinition as b0, getWorkflowStageIds as b1, findWorkflowStage as b2, getNextWorkflowStage as b3, getFirstWorkflowStage as b4, isFinalWorkflowStage as b5, workflowToJSON as b6, type WorkflowEscalation as b7, type WorkflowAutoAssign as b8, type WorkflowStageConfig as b9, type WhereOperator as bA, type SortCondition as bB, type SortDirection as bC, type IncludeDefinition as bD, type SelectMapping as bE, type FilterDefinition as bF, type CachePolicy as bG, type CachePolicyObject as bH, type IncludeSubQuery as bI, type IncludeSubQueries as bJ, type InferQueryResponse as bK, type InferQueryParams as bL, type WorkflowStageDefinition as ba, type WorkflowConfig as bb, type WorkflowDefinition as bc, type ContentTypeWorkflowConfig as bd, defineView as be, viewToJSON as bf, type ViewScopeConfig as bg, type ContentTypeScopeConfig as bh, type ContentTypesScopeConfig as bi, type EntryTypeScopeConfig as bj, type AllScopeConfig as bk, type ViewFilterOperator as bl, type ViewFilterCondition as bm, type ViewFilterGroup as bn, type ViewFilter as bo, type ViewConfig as bp, type ViewDefinition as bq, defineQuery as br, type QueryConfig as bs, type QueryDefinition as bt, type FetchBlock as bu, type AggregateBlock as bv, type SearchBlock as bw, type SimilarBlock as bx, type WhereCondition as by, type WhereValue as bz, type FieldDefinition as c, type LongTextConfig as d, type SlugConfig as e, type EnumConfig as f, type DateConfig as g, type DateTimeConfig as h, type ReferenceConfig as i, type ListConfig as j, type AllFieldTypes as k, type AnyFieldDefinition as l, type AssetAIConfig as m, type BaseFieldConfig as n, type FieldType as o, type ReadOnlyRule as p, type RequirementRule as q, type RuleCondition as r, type RuleConditions as s, type VisibilityRule as t, defineSchema as u, schemaToJSON as v, type SchemaConfig as w, type SchemaDefinition as x, type SchemaContentTypeNames as y, type SchemaSingletonNames as z };
|