@relyio/sdk 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +228 -0
  2. package/dist/{chunk-3DRDHXLY.js → chunk-5UMY6CS4.js} +435 -23
  3. package/dist/{chunk-FRJEUAAF.js → chunk-DBBZVZOS.js} +968 -2670
  4. package/dist/{chunk-DXCVO6M5.cjs → chunk-GUPV2M3X.cjs} +969 -2680
  5. package/dist/{chunk-POEEDYFM.js → chunk-PCFTJLEP.js} +543 -260
  6. package/dist/{chunk-FI5VIF4M.cjs → chunk-RSHMA4KT.cjs} +442 -22
  7. package/dist/{chunk-3MSFWXQL.cjs → chunk-X4KSS7PP.cjs} +542 -260
  8. package/dist/client/index.cjs +3 -3
  9. package/dist/client/index.d.cts +4 -5
  10. package/dist/client/index.d.ts +4 -5
  11. package/dist/client/index.js +1 -1
  12. package/dist/{include-paths-CL4gHv6I.d.cts → define-content-type-BUZeWtpk.d.cts} +4458 -1312
  13. package/dist/{include-paths-CrJNTsMl.d.ts → define-content-type-DOrZb_a_.d.ts} +4458 -1312
  14. package/dist/define-schema-5aHmsA8j.d.ts +699 -0
  15. package/dist/define-schema-nCfZeboB.d.cts +699 -0
  16. package/dist/index-B97ZDj44.d.ts +507 -0
  17. package/dist/index-C-pcllqY.d.cts +507 -0
  18. package/dist/index-DOhFQbv7.d.ts +3065 -0
  19. package/dist/index-DgVV5Nj7.d.cts +3065 -0
  20. package/dist/index.cjs +114 -147
  21. package/dist/index.d.cts +49 -87
  22. package/dist/index.d.ts +49 -87
  23. package/dist/index.js +5 -29
  24. package/dist/markdown/index.cjs +13750 -0
  25. package/dist/markdown/index.d.cts +111 -0
  26. package/dist/markdown/index.d.ts +111 -0
  27. package/dist/markdown/index.js +13742 -0
  28. package/dist/rich-text/index.cjs +26 -6
  29. package/dist/rich-text/index.d.cts +3 -148
  30. package/dist/rich-text/index.d.ts +3 -148
  31. package/dist/rich-text/index.js +1 -1
  32. package/dist/rich-text.d-BWc-5gX1.d.cts +326 -0
  33. package/dist/rich-text.d-BWc-5gX1.d.ts +326 -0
  34. package/dist/schema/index.cjs +33 -37
  35. package/dist/schema/index.d.cts +37 -191
  36. package/dist/schema/index.d.ts +37 -191
  37. package/dist/schema/index.js +1 -1
  38. package/dist/types/index.d.cts +2 -3
  39. package/dist/types/index.d.ts +2 -3
  40. package/package.json +14 -3
  41. package/dist/define-schema-DgctHlI2.d.cts +0 -1034
  42. package/dist/define-schema-mrEZbY1h.d.ts +0 -1034
  43. package/dist/index-B9RfZVF1.d.ts +0 -861
  44. package/dist/index-BrvEg6-A.d.cts +0 -3729
  45. package/dist/index-Pw0onkJe.d.ts +0 -3729
  46. package/dist/index-b-AkfTUv.d.cts +0 -861
  47. package/dist/rich-text.d-rKmpgdGd.d.cts +0 -200
  48. package/dist/rich-text.d-rKmpgdGd.d.ts +0 -200
@@ -1,1034 +0,0 @@
1
- import { a4 as ContentTypeDefinition, ab as SingletonContentTypeDefinition, ah as SettingsGroupDefinition, aU as WorkflowDefinition, am as AssetTypeDefinition, a6 as InferContentType } from './include-paths-CrJNTsMl.js';
2
-
3
- /**
4
- * Query definition matching @relyio/schema QueryDefinitionSchema
5
- *
6
- * Queries define predefined API endpoints with filtering, sorting, and caching.
7
- *
8
- * This is a hand-written mirror: `@relyio/sdk` is published standalone and does not depend on
9
- * `@relyio/schema`, so a field added there has to be added here too. When the two drifted, `limit`
10
- * was the casualty — the documentation writes `limit: '${limit?20}'` and this file said `number` —
11
- * and so were `fullText` and `type`, which a query pulled by `relyio generate-types` carried and
12
- * this refused. `@relyio/codegen-typescript`'s `src/__tests__/sdk-definition-config.types.ts` now
13
- * fails to compile when a key, whether it is required, or the values it accepts differs from the
14
- * schema's, block by block (REL-1457).
15
- */
16
- /** One value a query clause compares with. */
17
- type QueryScalar = string | number | boolean;
18
- /**
19
- * The operators `where` and `filters` compare a field with — `{ price: { gte: 10 } }`.
20
- *
21
- * The service's one vocabulary for `where`, `filters` and `having`, which deploy refuses any other
22
- * key against (REL-1479). There were four copies, and this one's `where` had no `eq` while `filters`
23
- * took six operators, each a `${…}` string. A value may be a parameter expression: a list operator
24
- * takes a list or a parameter that supplies one, a flag a boolean or a parameter.
25
- * `@relyio/codegen-typescript`'s `sdk-definition-config.types.ts` fails to compile when an operator,
26
- * or what it takes, differs from the schema's.
27
- */
28
- type WhereOperator = {
29
- /** Equal to */
30
- eq?: QueryScalar;
31
- /** Not equal to */
32
- ne?: QueryScalar;
33
- /** Greater than */
34
- gt?: QueryScalar;
35
- /** Greater than or equal to */
36
- gte?: QueryScalar;
37
- /** Less than */
38
- lt?: QueryScalar;
39
- /** Less than or equal to */
40
- lte?: QueryScalar;
41
- /** One of the values given */
42
- in?: QueryScalar[] | string;
43
- /** None of the values given */
44
- nin?: QueryScalar[] | string;
45
- /** Contains the text, ignoring case */
46
- contains?: QueryScalar;
47
- /** Starts with the text, ignoring case */
48
- startsWith?: QueryScalar;
49
- /** Ends with the text, ignoring case */
50
- endsWith?: QueryScalar;
51
- /** The field holds a value (true) or does not (false) */
52
- exists?: boolean | string;
53
- /** The field holds no value (true) or does (false) */
54
- notExists?: boolean | string;
55
- };
56
- /**
57
- * The operators `having` compares a metric with: the same as `where`'s, each with a literal, since
58
- * `having` reads the values the aggregate computed and substitutes no parameter.
59
- */
60
- type HavingOperator = {
61
- eq?: QueryScalar;
62
- ne?: QueryScalar;
63
- gt?: QueryScalar;
64
- gte?: QueryScalar;
65
- lt?: QueryScalar;
66
- lte?: QueryScalar;
67
- in?: QueryScalar[];
68
- nin?: QueryScalar[];
69
- contains?: QueryScalar;
70
- startsWith?: QueryScalar;
71
- endsWith?: QueryScalar;
72
- exists?: boolean;
73
- notExists?: boolean;
74
- };
75
- type WhereValue = string | number | boolean | (string | number | boolean)[] | WhereOperator;
76
- type WhereCondition = Record<string, WhereValue>;
77
- type SortDirection = 'asc' | 'desc';
78
- type SortCondition = Record<string, SortDirection> | Record<string, SortDirection>[];
79
- /**
80
- * A relationship joined by name — a reference the fetched type declares, or a reverse one another
81
- * type declares to it (`reviews`) — optionally filtered, counted and aliased:
82
- * `{ relationship: 'products', where: { status: 'active' }, aggregate: 'count', alias: 'productCount' }`.
83
- * `relationship` is a name, with no parentheses. A `select` reads what it joins.
84
- */
85
- type IncludeRelationship = {
86
- relationship: string;
87
- where?: WhereCondition;
88
- /**
89
- * What the include answers instead of the entries it joins. `count` is the one modifier: `sum`,
90
- * `avg`, `min` and `max` name no field to reduce — select one, like `products.price.sum` — and
91
- * the service refuses them (REL-1479).
92
- */
93
- aggregate?: 'count';
94
- /** The name the include answers under; the relationship's name when absent */
95
- alias?: string;
96
- };
97
- /**
98
- * What a fetch includes (REL-2035). A string is an **include path**, the grammar `?include=` and the
99
- * SDK's `include()` read: field ids joined by `.`, crossing lists, page builders, objects and
100
- * references, each hop written out, with the fields to return in parentheses —
101
- * `'sections.customers.logo'`, `'sections.features(name,slug)'`. The query returns what
102
- * `GET …?include=` returns for the same paths. A path's entries are expanded after the read, so a
103
- * `select` cannot read them: join a relationship for that ({@link IncludeRelationship}).
104
- */
105
- type IncludeDefinition = string | (string | IncludeRelationship)[];
106
- type SelectMapping = Record<string, string>;
107
- /** `filters` are `where` conditions bound at call time: the same operators, written the same way. */
108
- type FilterOperator = WhereOperator;
109
- type FilterDefinition = Record<string, string | FilterOperator>;
110
- /** A value that is either a literal or a `${param}` / `${param?default}` expression. */
111
- type Parameterizable<T> = T | string;
112
- type QueryParameterType = 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object';
113
- /**
114
- * A declared query parameter.
115
- *
116
- * Every `${...}` in a query and every `{name}` segment of its endpoint already declares one; this
117
- * block adds a type and constraints. Nothing is inferred from a parameter's name.
118
- */
119
- interface QueryParameter {
120
- /** The parameter, as it appears in `${...}` or in an endpoint segment */
121
- name: string;
122
- /** Coerces the caller's value; a value that will not coerce is a 400 */
123
- type?: QueryParameterType;
124
- /** Overrides what the query's own expressions say */
125
- required?: boolean;
126
- /** Used when the caller supplies nothing */
127
- default?: string | number | boolean | (string | number | boolean)[];
128
- minimum?: number;
129
- maximum?: number;
130
- /** String characters, or array items */
131
- minLength?: number;
132
- maxLength?: number;
133
- /** A regular expression, applied to strings */
134
- pattern?: string;
135
- enum?: (string | number | boolean)[];
136
- }
137
- /** Whether the query answers with one record or a list. Independent of how many rows match. */
138
- type QueryCardinality = 'one' | 'many';
139
- type CachePolicyObject = {
140
- /** Defaults to `public` */
141
- policy?: 'public' | 'private' | 'no-cache';
142
- ttl?: number;
143
- staleWhileRevalidate?: number;
144
- tags?: string[];
145
- };
146
- type CachePolicy = string | CachePolicyObject;
147
- /** A text search over `fields` the query runs beside its operation block. */
148
- type FullTextSearch = {
149
- /** The fields searched; at least one */
150
- fields: string[];
151
- /** The search text, usually a parameter expression such as `${q}` */
152
- query: string;
153
- highlight?: boolean;
154
- ranking?: 'simple' | 'complex';
155
- };
156
- /**
157
- * Fetch block - retrieve content entries
158
- */
159
- interface FetchBlock {
160
- /** Content type to fetch */
161
- contentType?: string;
162
- /** Singleton to fetch */
163
- singleton?: string;
164
- /** Filter conditions */
165
- where?: WhereCondition;
166
- /** Related content to include */
167
- include?: IncludeDefinition;
168
- /** Sort order */
169
- sort?: SortCondition;
170
- /** Maximum results */
171
- limit?: Parameterizable<number>;
172
- /** Results offset */
173
- offset?: Parameterizable<number>;
174
- }
175
- /**
176
- * Aggregate block - perform aggregations
177
- */
178
- interface AggregateBlock {
179
- /** Source content type (required when not used with fetch) */
180
- source?: string;
181
- /** Filter conditions */
182
- where?: WhereCondition;
183
- /** Group by field(s) */
184
- by?: string | string[] | (string | {
185
- expression: string;
186
- as?: string;
187
- })[];
188
- /**
189
- * What to compute per group, keyed by the name each answers under: `<field>.<fn>`, where `fn` is
190
- * `count`, `sum`, `avg`, `min`, `max`, `first` or `last` — `{ total: 'amount.sum' }`. Deploy
191
- * requires it. The one spelling: `aggregations`, which this type called the main one, was a
192
- * second name deploy refused (REL-1470).
193
- */
194
- metrics?: Record<string, string>;
195
- /** Having clause for filtering aggregations */
196
- having?: Record<string, QueryScalar | HavingOperator>;
197
- /** Sort order */
198
- sort?: SortCondition;
199
- /** Maximum results */
200
- limit?: Parameterizable<number>;
201
- }
202
- /**
203
- * Search block - full-text and semantic search
204
- */
205
- interface SearchBlock {
206
- /** Single content type */
207
- contentType?: string;
208
- /** Multiple content types or "*" for all */
209
- contentTypes?: string | string[] | '*';
210
- /** Search query string */
211
- query: string;
212
- /** Fields to search in */
213
- searchFields?: string[];
214
- /** Legacy search type */
215
- searchType?: 'plainto' | 'phraseto' | 'websearch' | 'to_tsquery';
216
- /** Filter conditions */
217
- where?: WhereCondition;
218
- /** Field mapping for results */
219
- fields?: SelectMapping;
220
- /** Include relevance score */
221
- includeRank?: boolean;
222
- /** Include score breakdown */
223
- explain?: boolean;
224
- /** Highlight matching terms */
225
- highlight?: boolean | {
226
- field?: string;
227
- maxWords?: number;
228
- minWords?: number;
229
- shortWord?: number;
230
- };
231
- /** Sort order */
232
- sort?: SortCondition;
233
- /** Maximum results */
234
- limit?: Parameterizable<number>;
235
- /** Results offset */
236
- offset?: Parameterizable<number>;
237
- }
238
- /**
239
- * Include sub-queries for additional data
240
- */
241
- interface IncludeSubQuery {
242
- source: string;
243
- where?: WhereCondition;
244
- sort?: SortCondition;
245
- limit?: Parameterizable<number>;
246
- select?: SelectMapping;
247
- }
248
- type IncludeSubQueries = Record<string, IncludeSubQuery>;
249
- /**
250
- * Which operation block a query runs. Inferred from the block it declares when absent.
251
- *
252
- * `similar` is not one: deploy refused a query built on it alone and nothing ran it. Similar
253
- * content is `relyio.similar(uid)` (REL-1470).
254
- */
255
- type QueryType = 'fetch' | 'aggregate' | 'search';
256
- /**
257
- * Query definition configuration
258
- */
259
- interface QueryConfig {
260
- /** Which operation block the query runs; inferred when absent */
261
- type?: QueryType;
262
- /** API endpoint path (required, e.g., /api/featured-products) */
263
- endpoint: string;
264
- /** Query description */
265
- description?: string;
266
- /** Fetch block for retrieving entries */
267
- fetch?: FetchBlock;
268
- /** Aggregate block for aggregations */
269
- aggregate?: AggregateBlock;
270
- /** Search block for full-text/semantic search */
271
- search?: SearchBlock;
272
- /** Include sub-queries */
273
- include?: IncludeSubQueries;
274
- /** Dynamic filter definitions */
275
- filters?: FilterDefinition;
276
- /** Full-text search over the fields it names */
277
- fullText?: FullTextSearch;
278
- /** Field selection/mapping */
279
- select?: SelectMapping;
280
- /** Cache policy */
281
- cache?: CachePolicy;
282
- /** Types and constraints for the parameters the query already declares by using them */
283
- parameters?: QueryParameter[];
284
- /** Whether the response is the record itself or a list. Defaults to `many` */
285
- cardinality?: QueryCardinality;
286
- }
287
- /**
288
- * Query definition
289
- */
290
- interface QueryDefinition {
291
- readonly _tag: 'query';
292
- readonly name: string;
293
- readonly type?: QueryType;
294
- readonly endpoint: string;
295
- readonly description?: string;
296
- readonly fetch?: FetchBlock;
297
- readonly aggregate?: AggregateBlock;
298
- readonly search?: SearchBlock;
299
- readonly include?: IncludeSubQueries;
300
- readonly filters?: FilterDefinition;
301
- readonly fullText?: FullTextSearch;
302
- readonly select?: SelectMapping;
303
- readonly cache?: CachePolicy;
304
- readonly parameters?: QueryParameter[];
305
- readonly cardinality?: QueryCardinality;
306
- }
307
- /**
308
- * Define a predefined query
309
- *
310
- * @example
311
- * const featuredProducts = defineQuery('featuredProducts', {
312
- * endpoint: '/api/featured-products',
313
- * description: 'Get featured products for homepage',
314
- * fetch: {
315
- * contentType: 'product',
316
- * where: {
317
- * status: 'active',
318
- * featured: true,
319
- * },
320
- * include: ['brand', 'categories'],
321
- * sort: { publishedAt: 'desc' },
322
- * limit: 10,
323
- * },
324
- * cache: {
325
- * policy: 'public',
326
- * ttl: 300,
327
- * staleWhileRevalidate: 60,
328
- * }
329
- * })
330
- *
331
- * @example
332
- * const searchProducts = defineQuery('searchProducts', {
333
- * endpoint: '/api/search',
334
- * description: 'Search products with semantic understanding',
335
- * search: {
336
- * contentType: 'product',
337
- * query: '${q}',
338
- * where: { status: 'active' },
339
- * highlight: true,
340
- * limit: 20,
341
- * },
342
- * filters: {
343
- * 'price.base': { gte: '${minPrice?0}', lte: '${maxPrice?}' },
344
- * category: '${categoryId?}',
345
- * },
346
- * cache: 'public 60s',
347
- * })
348
- *
349
- * @example
350
- * const productStats = defineQuery('productStats', {
351
- * endpoint: '/api/products/stats',
352
- * description: 'Get product statistics by category',
353
- * aggregate: {
354
- * source: 'product',
355
- * where: { status: 'active' },
356
- * by: ['category'],
357
- * metrics: {
358
- * totalProducts: 'id.count',
359
- * avgPrice: 'price.base.avg',
360
- * minPrice: 'price.base.min',
361
- * maxPrice: 'price.base.max',
362
- * },
363
- * sort: { totalProducts: 'desc' },
364
- * },
365
- * cache: 'public 300s',
366
- * })
367
- */
368
- declare function defineQuery(name: string, config: QueryConfig): QueryDefinition;
369
- /**
370
- * Infer basic response type from a query definition
371
- * Note: For accurate types, use the codegen tool
372
- */
373
- type InferQueryResponse<_T extends QueryDefinition> = unknown[];
374
- /**
375
- * Infer parameters from a query definition
376
- * Note: For accurate types, use the codegen tool
377
- */
378
- type InferQueryParams<_T extends QueryDefinition> = Record<string, unknown>;
379
-
380
- /**
381
- * Locale definition for multi-language support
382
- *
383
- * Locales define the languages and regions available for content
384
- * within your RelyIO project. Each locale can have:
385
- * - A fallback chain for missing content
386
- * - RTL text direction support
387
- * - Active/inactive status for gradual rollouts
388
- *
389
- * @example
390
- * import { defineLocale, defineSchema } from '@relyio/sdk/schema'
391
- *
392
- * const enUS = defineLocale('en-US', {
393
- * displayName: 'English (US)',
394
- * default: true,
395
- * })
396
- *
397
- * const esES = defineLocale('es-ES', {
398
- * displayName: 'Spanish (Spain)',
399
- * fallback: ['en-US'],
400
- * })
401
- *
402
- * const arSA = defineLocale('ar-SA', {
403
- * displayName: 'Arabic (Saudi Arabia)',
404
- * direction: 'rtl',
405
- * fallback: ['en-US'],
406
- * })
407
- *
408
- * export const schema = defineSchema({
409
- * locales: [enUS, esES, arSA],
410
- * contentTypes: { ... },
411
- * })
412
- */
413
- /**
414
- * Text direction for RTL language support
415
- */
416
- type TextDirection = 'ltr' | 'rtl';
417
- /**
418
- * Options for defining a locale
419
- */
420
- interface LocaleOptions {
421
- /** Human-readable name shown in the Studio UI */
422
- displayName: string;
423
- /**
424
- * Marks the default locale (exactly one required per schema)
425
- * The default locale serves as the ultimate fallback for all other locales
426
- */
427
- default?: boolean;
428
- /**
429
- * Ordered fallback chain when content is missing in this locale
430
- * Locales are tried in order until content is found
431
- *
432
- * @example
433
- * // Spanish Mexico falls back to Spain Spanish, then US English
434
- * fallback: ['es-ES', 'en-US']
435
- */
436
- fallback?: string[];
437
- /**
438
- * Text direction for RTL languages like Arabic, Hebrew
439
- * @default 'ltr'
440
- */
441
- direction?: TextDirection;
442
- /**
443
- * Enable/disable locale without removing translations
444
- * Useful for:
445
- * - Testing new locales before enabling them
446
- * - Temporarily disabling locales for compliance review
447
- * - Gradual market rollouts
448
- *
449
- * Note: Inactive locales can still serve as fallback targets
450
- * @default true
451
- */
452
- active?: boolean;
453
- }
454
- /**
455
- * Locale definition with type tag for SDK type inference
456
- */
457
- interface LocaleDefinition {
458
- readonly _tag: 'locale';
459
- readonly code: string;
460
- readonly displayName: string;
461
- readonly default?: boolean;
462
- readonly fallback?: readonly string[];
463
- readonly direction?: TextDirection;
464
- readonly active?: boolean;
465
- }
466
- /**
467
- * Define a locale for multi-language support
468
- *
469
- * Creates a locale definition that can be included in your schema.
470
- * Locales control:
471
- * - What languages/regions are available for content
472
- * - Fallback behavior when content is missing
473
- * - Text direction for RTL languages
474
- *
475
- * @param code BCP 47 locale code (e.g., 'en-US', 'fr-FR', 'ar-SA')
476
- * @param options Locale configuration
477
- * @returns Locale definition for use in defineSchema()
478
- *
479
- * @example
480
- * // Basic locale
481
- * const enUS = defineLocale('en-US', {
482
- * displayName: 'English (US)',
483
- * default: true,
484
- * })
485
- *
486
- * @example
487
- * // Locale with fallback chain
488
- * const esMX = defineLocale('es-MX', {
489
- * displayName: 'Spanish (Mexico)',
490
- * fallback: ['es-ES', 'en-US'],
491
- * })
492
- *
493
- * @example
494
- * // RTL language
495
- * const arSA = defineLocale('ar-SA', {
496
- * displayName: 'Arabic (Saudi Arabia)',
497
- * direction: 'rtl',
498
- * fallback: ['en-US'],
499
- * })
500
- *
501
- * @example
502
- * // Inactive locale for testing
503
- * const jaJP = defineLocale('ja-JP', {
504
- * displayName: 'Japanese',
505
- * fallback: ['en-US'],
506
- * active: false, // Hidden from Studio UI, but translations preserved
507
- * })
508
- */
509
- declare function defineLocale(code: string, options: LocaleOptions): LocaleDefinition;
510
- /**
511
- * Type guard to check if a value is a LocaleDefinition
512
- */
513
- declare function isLocaleDefinition(value: unknown): value is LocaleDefinition;
514
- /**
515
- * Extract locale codes from an array of locale definitions
516
- */
517
- declare function getLocaleCodes(locales: readonly LocaleDefinition[]): string[];
518
- /**
519
- * Find the default locale from an array of locale definitions
520
- */
521
- declare function findDefaultLocale(locales: readonly LocaleDefinition[]): LocaleDefinition | undefined;
522
- /**
523
- * Get active locales (excludes inactive ones)
524
- */
525
- declare function getActiveLocales(locales: readonly LocaleDefinition[]): LocaleDefinition[];
526
- /**
527
- * Build the complete fallback chain for a locale, resolving transitive fallbacks
528
- *
529
- * @param localeCode The locale to build the fallback chain for
530
- * @param locales All defined locales
531
- * @param maxDepth Maximum depth to prevent infinite loops (default: 10)
532
- * @returns Ordered array of locale codes to try as fallbacks
533
- *
534
- * @example
535
- * // Given: es-MX → es-ES → en-US (default)
536
- * buildFallbackChain('es-MX', locales)
537
- * // Returns: ['es-ES', 'en-US']
538
- */
539
- declare function buildFallbackChain(localeCode: string, locales: readonly LocaleDefinition[], maxDepth?: number): string[];
540
-
541
- /**
542
- * Role definition for fine-grained access control
543
- *
544
- * Roles define what users can do within a project. They can:
545
- * - Inherit from built-in roles (admin, editor, viewer)
546
- * - Compose from other roles using 'includes'
547
- * - Define granular permissions by access tags
548
- * - Set field visibility (hidden/readonly)
549
- */
550
- /**
551
- * Built-in roles that are always available
552
- */
553
- declare const BUILT_IN_ROLES: readonly ["admin", "editor", "viewer"];
554
- type BuiltInRole = (typeof BUILT_IN_ROLES)[number];
555
- /**
556
- * All available content actions
557
- */
558
- declare const ROLE_ACTIONS: readonly ["create", "read", "update", "delete", "publish", "unpublish", "duplicate", "comment", "approveElevated"];
559
- type RoleAction = (typeof ROLE_ACTIONS)[number];
560
- /**
561
- * Default actions for each built-in role
562
- */
563
- declare const BUILT_IN_ROLE_ACTIONS: Record<BuiltInRole, readonly RoleAction[]>;
564
- /**
565
- * Resource permission rule - defines what actions are allowed for specific tags
566
- */
567
- interface ResourcePermission {
568
- /** Access tags this permission applies to */
569
- tags: string[];
570
- /** Actions allowed for resources with these tags */
571
- actions: RoleAction[];
572
- }
573
- /**
574
- * Field visibility permissions
575
- */
576
- interface FieldVisibility {
577
- /** Fields that are hidden from this role (cannot see) */
578
- hidden?: string[];
579
- /** Fields that are readonly for this role (can see but not edit) */
580
- readonly?: string[];
581
- }
582
- /**
583
- * Role configuration
584
- */
585
- interface RoleConfig {
586
- /** Human-readable name shown in Studio */
587
- displayName: string;
588
- /** Optional description for administrators */
589
- description?: string;
590
- /** Inherit from a built-in role (admin, editor, viewer) */
591
- baseRole?: BuiltInRole;
592
- /** Compose from other roles (built-in or custom) */
593
- includes?: string[];
594
- /** Resource permission rules */
595
- permissions?: ResourcePermission[];
596
- /** Field visibility settings */
597
- fields?: FieldVisibility;
598
- }
599
- /**
600
- * Complete role definition
601
- */
602
- interface RoleDefinition {
603
- readonly _tag: 'role';
604
- readonly id: string;
605
- readonly displayName: string;
606
- readonly description?: string;
607
- readonly baseRole?: BuiltInRole;
608
- readonly includes?: string[];
609
- readonly permissions?: ResourcePermission[];
610
- readonly fields?: FieldVisibility;
611
- }
612
- /**
613
- * Define a custom role
614
- *
615
- * @example
616
- * // Inherit from built-in role
617
- * const blogEditor = defineRole('blog-editor', {
618
- * displayName: 'Blog Editor',
619
- * baseRole: 'editor',
620
- * permissions: [
621
- * { tags: ['blog'], actions: ['create', 'read', 'update', 'publish'] }
622
- * ]
623
- * })
624
- *
625
- * @example
626
- * // Compose from other roles
627
- * const seniorEditor = defineRole('senior-editor', {
628
- * displayName: 'Senior Editor',
629
- * includes: ['blog-editor', 'news-editor'],
630
- * permissions: [
631
- * { tags: ['featured'], actions: ['publish', 'unpublish'] }
632
- * ]
633
- * })
634
- *
635
- * @example
636
- * // Full permissions control
637
- * const moderator = defineRole('moderator', {
638
- * displayName: 'Content Moderator',
639
- * permissions: [
640
- * { tags: ['comments'], actions: ['read', 'delete'] }
641
- * ],
642
- * fields: {
643
- * hidden: ['internalNotes'],
644
- * readonly: ['authorId']
645
- * }
646
- * })
647
- */
648
- declare function defineRole(id: string, config: RoleConfig): RoleDefinition;
649
- /**
650
- * Check if a value is a role definition
651
- */
652
- declare function isRoleDefinition(value: unknown): value is RoleDefinition;
653
- /**
654
- * Check if a role ID is a built-in role
655
- */
656
- declare function isBuiltInRole(roleId: string): roleId is BuiltInRole;
657
- /**
658
- * Get the default actions for a built-in role
659
- */
660
- declare function getBuiltInRoleActions(roleId: BuiltInRole): readonly RoleAction[];
661
-
662
- /**
663
- * View definitions for SDK schema
664
- *
665
- * Views define pre-configured entry list configurations with filters,
666
- * columns, and metadata display settings.
667
- */
668
- /**
669
- * View scope defines which content types a view applies to.
670
- *
671
- * When using `contentTypes` (plural) or `all`, the view displays entries
672
- * from multiple content types. In this case:
673
- *
674
- * - Columns/fields may only exist on some content types
675
- * - For entries where a field doesn't exist, the UI displays "—"
676
- * - System fields (id, status, createdAt, updatedAt) exist on all entries
677
- * - Filters on non-existent fields are skipped for that entry type
678
- *
679
- * Example display:
680
- * | Content Type | title | author | productCode |
681
- * |--------------|-------|--------|-------------|
682
- * | post | ✓ | ✓ | — |
683
- * | product | ✓ | — | ✓ |
684
- */
685
- /**
686
- * Scope for a single content type
687
- */
688
- interface ContentTypeScopeConfig {
689
- type: 'contentType';
690
- contentType: string;
691
- }
692
- /**
693
- * Scope for multiple content types
694
- *
695
- * Fields not present on all content types will show "—" in the UI
696
- */
697
- interface ContentTypesScopeConfig {
698
- type: 'contentTypes';
699
- contentTypes: string[];
700
- }
701
- /**
702
- * Scope for an entry type (content, singleton, settings, asset)
703
- */
704
- interface EntryTypeScopeConfig {
705
- type: 'entryType';
706
- entryType: 'content' | 'singleton' | 'settings' | 'asset';
707
- }
708
- /**
709
- * Scope for all content
710
- *
711
- * Fields not present on all content types will show "—" in the UI
712
- */
713
- interface AllScopeConfig {
714
- type: 'all';
715
- }
716
- /**
717
- * View scope options
718
- */
719
- type ViewScopeConfig = ContentTypeScopeConfig | ContentTypesScopeConfig | EntryTypeScopeConfig | AllScopeConfig;
720
- /**
721
- * The operators a view filter may name: the schema's `FILTER_OPERATORS`, which deploy parses a view
722
- * with and the read core compiles every one of.
723
- *
724
- * This list used to be its own: ten of its names — `doesNotContain`, `isNotEmpty`, `isOnOrBefore`,
725
- * `isOnOrAfter`, `tomorrow`, `lastWeek`, `lastMonth`, `includesAll`, `includesAny`, `excludes` —
726
- * are none the schema declares, so a view naming one was refused at deploy, and six the schema does
727
- * declare — `notContains`, `notIncludes`, `isOn`, `isBetween`, `thisYear`, `hasValue` — could not be
728
- * written here, so a view pulled by `relyio generate-types` that named one did not compile.
729
- * `@relyio/codegen-typescript`'s `src/__tests__/sdk-definition-config.types.ts` holds the two to each
730
- * other (REL-1457).
731
- */
732
- type ViewFilterOperator = 'is' | 'isNot' | 'contains' | 'notContains' | 'startsWith' | 'endsWith' | 'isAnyOf' | 'isNoneOf' | 'includes' | 'notIncludes' | 'isTrue' | 'isFalse' | 'equals' | 'notEquals' | 'greaterThan' | 'lessThan' | 'greaterThanOrEqual' | 'lessThanOrEqual' | 'between' | 'isOn' | 'isBefore' | 'isAfter' | 'isBetween' | 'inTheLast' | 'inTheNext' | 'today' | 'yesterday' | 'thisWeek' | 'thisMonth' | 'thisYear' | 'isEmpty' | 'hasValue';
733
- /** A span of time back or forward from now, for `inTheLast` and `inTheNext`. */
734
- interface ViewFilterRelativeDate {
735
- amount: number;
736
- unit: 'minutes' | 'hours' | 'days' | 'weeks' | 'months' | 'years';
737
- }
738
- /** What a filter compares against: the schema's `FilterValueSchema`. */
739
- type ViewFilterValue = string | number | boolean | null | (string | number)[] | {
740
- from: string | number | Date;
741
- to: string | number | Date;
742
- } | ViewFilterRelativeDate | Date;
743
- /**
744
- * One filter of a view: a field, an operator and the value it compares with.
745
- */
746
- interface ViewFilterCondition {
747
- /**
748
- * The Property to filter on, as the Studio's entry list names it: `fields.<id>` for a field your
749
- * schema declares (`fields.seo.title` for a field of an object's value), `_metadata.<id>` for a system
750
- * field — `_metadata.status`, `_metadata.createdAt`, `_metadata.updatedAt`. So a field called
751
- * `status` (`fields.status`) and the entry's own lifecycle (`_metadata.status`) are both
752
- * filterable.
753
- */
754
- field: string;
755
- /**
756
- * Filter operator
757
- */
758
- operator: ViewFilterOperator;
759
- /**
760
- * Filter value (optional for some operators like isEmpty)
761
- */
762
- value?: ViewFilterValue;
763
- }
764
- /**
765
- * A view's filter. A view's filters are a flat list joined by AND — the Filters the Studio's entry
766
- * list takes, each drawn as a Chip — so there is no filter group: an OR within one field is
767
- * `isAnyOf`. RelyIO refuses a group by name when you deploy.
768
- */
769
- type ViewFilter = ViewFilterCondition;
770
- /**
771
- * View definition configuration
772
- */
773
- interface ViewConfig {
774
- /**
775
- * Display name for the view
776
- */
777
- name: string;
778
- /**
779
- * URL-friendly slug for the view, used in Studio URLs like /studio/views/:slug. Absent, the
780
- * platform derives one from the id when it reads the schema.
781
- */
782
- slug?: string;
783
- /**
784
- * Optional description for the view
785
- */
786
- description?: string;
787
- /**
788
- * Icon (emoji or icon name) for the view
789
- */
790
- icon?: string;
791
- /**
792
- * Color for the view in the sidebar
793
- */
794
- color?: string;
795
- /**
796
- * View scope - what content types this view applies to
797
- */
798
- scope: ViewScopeConfig;
799
- /**
800
- * Filter conditions (optional), combined with AND. A flat list: an OR within one field is
801
- * `isAnyOf`, and there is no filter group.
802
- *
803
- * Deploy judges each against the entries the view lists: the field must be one they can be
804
- * narrowed by, and it must offer the operator — a boolean field takes `is` with `true` or
805
- * `false`, for example, not `isTrue`.
806
- */
807
- filters?: ViewFilter[];
808
- /**
809
- * Column field IDs to display (optional)
810
- * If not specified, uses default columns
811
- */
812
- columns?: string[];
813
- /**
814
- * Metadata field IDs to show under title (max 3)
815
- */
816
- metadataFields?: string[];
817
- /**
818
- * Default sort (optional). `field` names the Property to sort by, as a filter names one —
819
- * `fields.<id>` or `_metadata.<id>` — and deploy refuses one the view's entries cannot be sorted
820
- * by. `columns` and `metadataFields` are display settings and name field IDs as written.
821
- */
822
- sort?: {
823
- field: string;
824
- direction: 'asc' | 'desc';
825
- };
826
- /**
827
- * Sort order in the sidebar (lower = higher priority)
828
- */
829
- sortOrder?: number;
830
- }
831
- /**
832
- * Complete view definition with ID
833
- */
834
- interface ViewDefinition extends ViewConfig {
835
- /**
836
- * Internal tag for type discrimination
837
- */
838
- readonly _tag: 'view';
839
- /**
840
- * Unique view ID (must start with a letter)
841
- */
842
- readonly id: string;
843
- }
844
- /**
845
- * Define a schema view
846
- *
847
- * Views are pre-configured entry list displays with filters,
848
- * columns, and metadata settings.
849
- *
850
- * @example
851
- * const featuredPosts = defineView('featuredPosts', {
852
- * name: 'Featured Posts',
853
- * description: 'Blog posts marked as featured',
854
- * icon: '📝',
855
- * scope: { type: 'contentType', contentType: 'post' },
856
- * filters: [
857
- * { field: 'fields.featured', operator: 'is', value: true }
858
- * ],
859
- * columns: ['title', 'author', 'publishedAt'],
860
- * metadataFields: ['category', 'views'],
861
- * sort: { field: '_metadata.publishedAt', direction: 'desc' }
862
- * })
863
- *
864
- * @example
865
- * const archivedContent = defineView('archivedContent', {
866
- * name: 'Archived',
867
- * scope: { type: 'all' },
868
- * filters: [
869
- * { field: '_metadata.status', operator: 'is', value: 'archived' }
870
- * ]
871
- * })
872
- *
873
- * @param id - Unique view ID (must start with a letter)
874
- * @param config - View configuration
875
- * @returns View definition object
876
- */
877
- declare function defineView(id: string, config: ViewConfig): ViewDefinition;
878
-
879
- /**
880
- * Schema definition matching @relyio/schema SchemaDefinitionSchema
881
- *
882
- * Note: `version` is NOT user-defined - it's auto-generated by the backend.
883
- */
884
-
885
- /**
886
- * Schema configuration
887
- *
888
- * Matches the SchemaDefinitionSchema from @relyio/schema:
889
- * - locales: Optional array of locale definitions for multi-language support
890
- * - contentTypes: Required record of content type definitions
891
- * - singletonContentTypes: Required record of singleton definitions (can be empty {})
892
- * - queries: Required record of query definitions (can be empty {})
893
- * - settingsGroups: Optional record of settings groups
894
- * - roles: Optional array of custom role definitions for access control
895
- * - workflow: Optional workflow configuration with approval stages
896
- *
897
- * Note: `version` is auto-generated by the backend, not user-defined!
898
- */
899
- interface SchemaConfig {
900
- /** Locale definitions for multi-language support (optional) */
901
- locales?: LocaleDefinition[];
902
- /** Content type definitions (required) */
903
- contentTypes: Record<string, ContentTypeDefinition>;
904
- /** Singleton content type definitions (required, can be empty) */
905
- singletonContentTypes?: Record<string, SingletonContentTypeDefinition>;
906
- /** Predefined query definitions (required, can be empty) */
907
- queries?: Record<string, QueryDefinition>;
908
- /** Settings group definitions (optional) */
909
- settingsGroups?: Record<string, SettingsGroupDefinition>;
910
- /** Asset type definitions (optional) */
911
- assetTypes?: Record<string, AssetTypeDefinition>;
912
- /** Custom role definitions for fine-grained access control (optional) */
913
- roles?: RoleDefinition[];
914
- /** Global workflow configuration with approval stages (optional) */
915
- workflow?: WorkflowDefinition;
916
- /** View definitions for pre-configured entry list views (optional) */
917
- views?: ViewDefinition[];
918
- }
919
- /**
920
- * Complete schema definition - Generic version for type inference
921
- */
922
- interface SchemaDefinition<TContentTypes extends Record<string, ContentTypeDefinition> = Record<string, ContentTypeDefinition>, 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>> {
923
- readonly _tag: 'schema';
924
- readonly locales?: TLocales;
925
- readonly contentTypes: TContentTypes;
926
- readonly singletonContentTypes: TSingletons;
927
- readonly queries: TQueries;
928
- readonly settingsGroups?: TSettings;
929
- readonly assetTypes?: TAssets;
930
- readonly roles?: TRoles;
931
- readonly workflow?: TWorkflow;
932
- readonly views?: TViews;
933
- }
934
- /**
935
- * Typed schema config for type inference
936
- */
937
- interface TypedSchemaConfig<TContentTypes extends Record<string, ContentTypeDefinition>, 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>> {
938
- locales?: TLocales;
939
- contentTypes: TContentTypes;
940
- singletonContentTypes?: TSingletons;
941
- queries?: TQueries;
942
- settingsGroups?: TSettings;
943
- assetTypes?: TAssets;
944
- roles?: TRoles;
945
- workflow?: TWorkflow;
946
- views?: TViews;
947
- }
948
- /**
949
- * Define a complete schema
950
- *
951
- * This creates a schema definition that can be:
952
- * 1. Deployed via the CLI
953
- * 2. Used for type inference in the SDK client
954
- *
955
- * @example
956
- * import { defineSchema, defineContentType, defineLocale, fields } from '@relyio/sdk/schema'
957
- *
958
- * const enUS = defineLocale('en-US', { displayName: 'English (US)', default: true })
959
- * const esES = defineLocale('es-ES', { displayName: 'Spanish', fallback: ['en-US'] })
960
- *
961
- * const product = defineContentType('product', {
962
- * displayName: 'Product',
963
- * fields: [
964
- * fields.shortText('title', { config: { required: true }, localization: true }),
965
- * fields.decimal('price', { config: { min: 0, decimalPlaces: 2 } }),
966
- * // One value of a fieldset: `{ _type: 'seo', _key, metaTitle?, metaDescription? }`
967
- * fields.object('seo', {
968
- * config: {
969
- * of: {
970
- * id: 'seo',
971
- * displayName: 'SEO Metadata',
972
- * fields: [
973
- * fields.shortText('metaTitle', { config: { maxLength: 60 } }),
974
- * fields.longText('metaDescription', { config: { maxLength: 160 } }),
975
- * ],
976
- * },
977
- * },
978
- * }),
979
- * ]
980
- * })
981
- *
982
- * export const schema = defineSchema({
983
- * locales: [enUS, esES],
984
- * contentTypes: { product },
985
- * })
986
- */
987
- declare function defineSchema<TContentTypes extends Record<string, ContentTypeDefinition>, 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, TSingletons, TQueries, TSettings, TLocales, TRoles, TWorkflow, TViews, TAssets>): SchemaDefinition<TContentTypes, TSingletons, TQueries, TSettings, TLocales, TRoles, TWorkflow, TViews, TAssets>;
988
- /**
989
- * Type alias for any schema definition.
990
- * Uses `any` intentionally for type inference utilities that need to accept any schema.
991
- */
992
- type AnySchemaDefinition = SchemaDefinition<any, any, any, any, any, any, any, any, any>;
993
- /**
994
- * Get content type names from a schema
995
- */
996
- type SchemaContentTypeNames<T extends AnySchemaDefinition> = keyof T['contentTypes'] & string;
997
- /**
998
- * An entry of content type `K`, typed by schema `T` as a read returns it — what `content(K)` reads,
999
- * with references resolved against `T` (`INV-SS-TYPES-INFERRED`).
1000
- */
1001
- type SchemaEntry<T extends AnySchemaDefinition, K extends SchemaContentTypeNames<T>> = InferContentType<T['contentTypes'][K], T>;
1002
- /**
1003
- * An entry of any one of the content types `K` names — every content type by default — as a search
1004
- * across them returns it: a union, so `_metadata.type` tells a caller which it holds.
1005
- */
1006
- type SchemaEntryOf<T extends AnySchemaDefinition, K extends SchemaContentTypeNames<T> = SchemaContentTypeNames<T>> = {
1007
- [N in K]: SchemaEntry<T, N>;
1008
- }[K];
1009
- /**
1010
- * Get singleton names from a schema
1011
- */
1012
- type SchemaSingletonNames<T extends AnySchemaDefinition> = keyof T['singletonContentTypes'] & string;
1013
- /**
1014
- * Get query names from a schema
1015
- */
1016
- type SchemaQueryNames<T extends AnySchemaDefinition> = keyof T['queries'] & string;
1017
- /**
1018
- * Get settings group names from a schema.
1019
- *
1020
- * `settingsGroups`, `assetTypes` and `locales` are optional members of `SchemaDefinition`, so
1021
- * indexing one yields `X | undefined`, which never extends the record — every typed client's
1022
- * `settings()`, `asset()` and `withLocale()` took `never`. The three read through `NonNullable`.
1023
- */
1024
- type SchemaSettingsGroupNames<T extends AnySchemaDefinition> = NonNullable<T['settingsGroups']> extends Record<string, SettingsGroupDefinition> ? keyof NonNullable<T['settingsGroups']> & string : never;
1025
- /**
1026
- * Get asset type names from a schema
1027
- */
1028
- type SchemaAssetTypeNames<T extends AnySchemaDefinition> = NonNullable<T['assetTypes']> extends Record<string, AssetTypeDefinition> ? keyof NonNullable<T['assetTypes']> & string : never;
1029
- /**
1030
- * Get locale codes from a schema
1031
- */
1032
- type SchemaLocaleCodes<T extends AnySchemaDefinition> = NonNullable<T['locales']> extends readonly LocaleDefinition[] ? NonNullable<T['locales']>[number]['code'] : never;
1033
-
1034
- export { type SearchBlock as $, type RoleDefinition as A, BUILT_IN_ROLES as B, defineView as C, type ContentTypeScopeConfig as D, type ContentTypesScopeConfig as E, type FieldVisibility as F, type EntryTypeScopeConfig as G, type AllScopeConfig as H, type ViewFilterOperator as I, type ViewFilterValue as J, type ViewFilterRelativeDate as K, type LocaleOptions as L, type ViewFilterCondition as M, type ViewFilter as N, type ViewConfig as O, type ViewDefinition as P, defineQuery as Q, ROLE_ACTIONS as R, type SchemaConfig as S, type TextDirection as T, type QueryConfig as U, type ViewScopeConfig as V, type QueryDefinition as W, type QueryType as X, type FullTextSearch as Y, type FetchBlock as Z, type AggregateBlock as _, type SchemaDefinition as a, type WhereCondition as a0, type WhereValue as a1, type WhereOperator as a2, type HavingOperator as a3, type QueryScalar as a4, type SortCondition as a5, type SortDirection as a6, type IncludeDefinition as a7, type IncludeRelationship as a8, type SelectMapping as a9, type FilterDefinition as aa, type CachePolicy as ab, type CachePolicyObject as ac, type IncludeSubQuery as ad, type IncludeSubQueries as ae, type Parameterizable as af, type QueryParameter as ag, type QueryParameterType as ah, type QueryCardinality as ai, type InferQueryResponse as aj, type InferQueryParams as ak, type FilterOperator as al, type SchemaContentTypeNames as b, type SchemaSingletonNames as c, defineSchema as d, type SchemaQueryNames as e, type SchemaLocaleCodes as f, type SchemaSettingsGroupNames as g, type SchemaAssetTypeNames as h, type SchemaEntry as i, type SchemaEntryOf as j, defineLocale as k, isLocaleDefinition as l, getLocaleCodes as m, findDefaultLocale as n, getActiveLocales as o, buildFallbackChain as p, type LocaleDefinition as q, defineRole as r, isRoleDefinition as s, isBuiltInRole as t, getBuiltInRoleActions as u, BUILT_IN_ROLE_ACTIONS as v, type BuiltInRole as w, type RoleAction as x, type ResourcePermission as y, type RoleConfig as z };