@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.
Files changed (45) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/LICENSE +201 -0
  3. package/README.md +314 -0
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/chunk-2QUK2ZGD.js +738 -0
  6. package/dist/chunk-7W4MJXQ4.cjs +4429 -0
  7. package/dist/chunk-FJK7ZWKK.cjs +776 -0
  8. package/dist/chunk-HT6NFRM2.cjs +196 -0
  9. package/dist/chunk-I3ESNANB.js +177 -0
  10. package/dist/chunk-IY5LSKXU.js +3 -0
  11. package/dist/chunk-MWMSFIWN.cjs +17 -0
  12. package/dist/chunk-PPA2WWOH.cjs +4 -0
  13. package/dist/chunk-RJBIJ2ZK.js +4375 -0
  14. package/dist/chunk-XQ4QHWZE.js +13 -0
  15. package/dist/client/index.cjs +17 -0
  16. package/dist/client/index.d.cts +3 -0
  17. package/dist/client/index.d.ts +3 -0
  18. package/dist/client/index.js +4 -0
  19. package/dist/define-schema-DHvUCKwj.d.cts +2101 -0
  20. package/dist/define-schema-DHvUCKwj.d.ts +2101 -0
  21. package/dist/index-B-KiFHbx.d.ts +2708 -0
  22. package/dist/index-BsUqCAu8.d.cts +7855 -0
  23. package/dist/index-BsUqCAu8.d.ts +7855 -0
  24. package/dist/index-DGWaawHt.d.cts +2708 -0
  25. package/dist/index.cjs +499 -0
  26. package/dist/index.d.cts +523 -0
  27. package/dist/index.d.ts +523 -0
  28. package/dist/index.js +148 -0
  29. package/dist/react/index.cjs +4 -0
  30. package/dist/react/index.d.cts +2 -0
  31. package/dist/react/index.d.ts +2 -0
  32. package/dist/react/index.js +3 -0
  33. package/dist/schema/index.cjs +157 -0
  34. package/dist/schema/index.d.cts +223 -0
  35. package/dist/schema/index.d.ts +223 -0
  36. package/dist/schema/index.js +4 -0
  37. package/dist/types/index.cjs +6 -0
  38. package/dist/types/index.d.cts +1 -0
  39. package/dist/types/index.d.ts +1 -0
  40. package/dist/types/index.js +3 -0
  41. package/dist/utils/index.cjs +81 -0
  42. package/dist/utils/index.d.cts +87 -0
  43. package/dist/utils/index.d.ts +87 -0
  44. package/dist/utils/index.js +4 -0
  45. package/package.json +159 -0
@@ -0,0 +1,738 @@
1
+ import { __name, __export } from './chunk-XQ4QHWZE.js';
2
+
3
+ /* RelyIO SDK - Built with ❤️ by the RelyIO Team */
4
+
5
+ // src/schema/define-workflow.ts
6
+ function defineWorkflowStage(id, config) {
7
+ if (!id || id.length === 0) {
8
+ throw new Error("Workflow stage ID is required");
9
+ }
10
+ const stageIdPattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$|^[a-z][a-zA-Z0-9]*$/;
11
+ if (!stageIdPattern.test(id)) {
12
+ throw new Error(
13
+ `Workflow stage ID '${id}' must be kebab-case (e.g., editorial-review) or camelCase (e.g., editorialReview)`
14
+ );
15
+ }
16
+ if (id.length > 64) {
17
+ throw new Error(`Workflow stage ID '${id}' must be 64 characters or less`);
18
+ }
19
+ if (!config.displayName || config.displayName.length === 0) {
20
+ throw new Error("Workflow stage displayName is required");
21
+ }
22
+ if (config.displayName.length > 128) {
23
+ throw new Error(`Workflow stage displayName must be 128 characters or less`);
24
+ }
25
+ if (config.description != null && config.description.length > 512) {
26
+ throw new Error(`Workflow stage description must be 512 characters or less`);
27
+ }
28
+ const requiredApprovals = config.requiredApprovals ?? 1;
29
+ if (requiredApprovals < 1 || requiredApprovals > 10) {
30
+ throw new Error(`requiredApprovals must be between 1 and 10`);
31
+ }
32
+ if (config.timeoutDays !== void 0) {
33
+ if (config.timeoutDays < 1 || config.timeoutDays > 365) {
34
+ throw new Error(`timeoutDays must be between 1 and 365`);
35
+ }
36
+ }
37
+ if (config.autoAssign) {
38
+ if (!Array.isArray(config.autoAssign.roles) || config.autoAssign.roles.length === 0) {
39
+ throw new Error(`autoAssign.roles must be a non-empty array`);
40
+ }
41
+ }
42
+ return {
43
+ _tag: "workflowStage",
44
+ id,
45
+ displayName: config.displayName,
46
+ ...config.description !== void 0 && config.description !== "" && { description: config.description },
47
+ requiredApprovals,
48
+ ...config.allowedRoles !== void 0 && config.allowedRoles.length > 0 && { allowedRoles: config.allowedRoles },
49
+ ...config.autoAssign !== void 0 && { autoAssign: config.autoAssign },
50
+ ...config.timeoutDays !== void 0 && { timeoutDays: config.timeoutDays },
51
+ ...config.escalation !== void 0 && { escalation: config.escalation }
52
+ };
53
+ }
54
+ __name(defineWorkflowStage, "defineWorkflowStage");
55
+ function defineWorkflow(config) {
56
+ const enabled = config.enabled ?? false;
57
+ const stages = config.stages ?? [];
58
+ if (stages.length > 0) {
59
+ const stageIds = /* @__PURE__ */ new Set();
60
+ for (const stage of stages) {
61
+ if (stageIds.has(stage.id)) {
62
+ throw new Error(`Duplicate workflow stage ID '${stage.id}'`);
63
+ }
64
+ stageIds.add(stage.id);
65
+ }
66
+ }
67
+ return {
68
+ _tag: "workflow",
69
+ enabled,
70
+ stages
71
+ };
72
+ }
73
+ __name(defineWorkflow, "defineWorkflow");
74
+ function defineContentTypeWorkflow(config) {
75
+ return {
76
+ ...config.enabled !== void 0 && { enabled: config.enabled },
77
+ ...config.stages !== void 0 && config.stages.length > 0 && { stages: config.stages },
78
+ ...config.autoPublish !== void 0 && { autoPublish: config.autoPublish },
79
+ ...config.requireAllLocales !== void 0 && { requireAllLocales: config.requireAllLocales }
80
+ };
81
+ }
82
+ __name(defineContentTypeWorkflow, "defineContentTypeWorkflow");
83
+ function isWorkflowStageDefinition(value) {
84
+ return typeof value === "object" && value !== null && "_tag" in value && value._tag === "workflowStage";
85
+ }
86
+ __name(isWorkflowStageDefinition, "isWorkflowStageDefinition");
87
+ function isWorkflowDefinition(value) {
88
+ return typeof value === "object" && value !== null && "_tag" in value && value._tag === "workflow";
89
+ }
90
+ __name(isWorkflowDefinition, "isWorkflowDefinition");
91
+ function getWorkflowStageIds(workflow) {
92
+ return workflow.stages.map((s) => s.id);
93
+ }
94
+ __name(getWorkflowStageIds, "getWorkflowStageIds");
95
+ function findWorkflowStage(workflow, stageId) {
96
+ return workflow.stages.find((s) => s.id === stageId);
97
+ }
98
+ __name(findWorkflowStage, "findWorkflowStage");
99
+ function getNextWorkflowStage(workflow, currentStageId) {
100
+ const currentIndex = workflow.stages.findIndex((s) => s.id === currentStageId);
101
+ if (currentIndex === -1 || currentIndex === workflow.stages.length - 1) {
102
+ return null;
103
+ }
104
+ const nextStage = workflow.stages[currentIndex + 1];
105
+ return nextStage ?? null;
106
+ }
107
+ __name(getNextWorkflowStage, "getNextWorkflowStage");
108
+ function getFirstWorkflowStage(workflow) {
109
+ if (workflow.stages.length === 0) return null;
110
+ const firstStage = workflow.stages[0];
111
+ return firstStage ?? null;
112
+ }
113
+ __name(getFirstWorkflowStage, "getFirstWorkflowStage");
114
+ function isFinalWorkflowStage(workflow, stageId) {
115
+ if (workflow.stages.length === 0) return false;
116
+ const lastStage = workflow.stages[workflow.stages.length - 1];
117
+ return lastStage?.id === stageId;
118
+ }
119
+ __name(isFinalWorkflowStage, "isFinalWorkflowStage");
120
+ function workflowToJSON(workflow) {
121
+ return {
122
+ enabled: workflow.enabled,
123
+ ...workflow.stages.length > 0 && {
124
+ stages: workflow.stages.map((stage) => {
125
+ const { _tag: _, ...rest } = stage;
126
+ return rest;
127
+ })
128
+ }
129
+ };
130
+ }
131
+ __name(workflowToJSON, "workflowToJSON");
132
+
133
+ // src/schema/define-view.ts
134
+ function generateSlugFromId(id) {
135
+ return id.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[_\s]+/g, "-").toLowerCase();
136
+ }
137
+ __name(generateSlugFromId, "generateSlugFromId");
138
+ function defineView(id, config) {
139
+ if (!id.match(/^[a-zA-Z][a-zA-Z0-9_-]*$/)) {
140
+ throw new Error(
141
+ `View ID '${id}' must start with a letter and contain only letters, numbers, underscores, and hyphens`
142
+ );
143
+ }
144
+ if (!config.name || config.name.length === 0) {
145
+ throw new Error(`View '${id}' must have a name`);
146
+ }
147
+ if (config.metadataFields && config.metadataFields.length > 3) {
148
+ throw new Error(`View '${id}' can have at most 3 metadata fields`);
149
+ }
150
+ if (!config.scope?.type) {
151
+ throw new Error(`View '${id}' must have a valid scope`);
152
+ }
153
+ const slug2 = config.slug ?? generateSlugFromId(id);
154
+ if (!slug2.match(/^[a-z][a-z0-9-]*$/)) {
155
+ throw new Error(
156
+ `View '${id}' slug '${slug2}' must be lowercase, start with a letter, and contain only letters, numbers, and hyphens`
157
+ );
158
+ }
159
+ return {
160
+ _tag: "view",
161
+ id,
162
+ slug: slug2,
163
+ ...config
164
+ };
165
+ }
166
+ __name(defineView, "defineView");
167
+ function viewToJSON(view) {
168
+ const { _tag, ...rest } = view;
169
+ return rest;
170
+ }
171
+ __name(viewToJSON, "viewToJSON");
172
+
173
+ // src/schema/define-schema.ts
174
+ function defineSchema(config) {
175
+ if (config.contentTypes == null || Object.keys(config.contentTypes).length === 0) {
176
+ throw new Error("Schema must have at least one content type");
177
+ }
178
+ if (config.locales && config.locales.length > 0) {
179
+ const defaultLocales = config.locales.filter((l) => l.default === true);
180
+ if (defaultLocales.length === 0) {
181
+ throw new Error("Schema with locales must have exactly one default locale");
182
+ }
183
+ if (defaultLocales.length > 1) {
184
+ throw new Error(
185
+ `Schema has ${defaultLocales.length} default locales. Only one locale can be the default.`
186
+ );
187
+ }
188
+ const codes = config.locales.map((l) => l.code);
189
+ const uniqueCodes = new Set(codes);
190
+ if (codes.length !== uniqueCodes.size) {
191
+ throw new Error("Schema has duplicate locale codes");
192
+ }
193
+ for (const locale of config.locales) {
194
+ if (locale.fallback) {
195
+ for (const fallbackCode of locale.fallback) {
196
+ if (!uniqueCodes.has(fallbackCode)) {
197
+ throw new Error(
198
+ `Locale '${locale.code}' has fallback to non-existent locale '${fallbackCode}'`
199
+ );
200
+ }
201
+ }
202
+ }
203
+ }
204
+ }
205
+ if (config.roles && config.roles.length > 0) {
206
+ const roleIds = /* @__PURE__ */ new Set();
207
+ for (const role of config.roles) {
208
+ if (roleIds.has(role.id)) {
209
+ throw new Error(`Duplicate role ID '${role.id}'`);
210
+ }
211
+ roleIds.add(role.id);
212
+ }
213
+ }
214
+ if (config.workflow) {
215
+ const builtInRoles = /* @__PURE__ */ new Set(["admin", "editor", "viewer"]);
216
+ const customRoleIds = new Set(config.roles?.map((r) => r.id) ?? []);
217
+ const allRoleIds = /* @__PURE__ */ new Set([...builtInRoles, ...customRoleIds]);
218
+ for (const stage of config.workflow.stages) {
219
+ if (stage.allowedRoles) {
220
+ for (const roleId of stage.allowedRoles) {
221
+ if (!allRoleIds.has(roleId)) {
222
+ throw new Error(`Workflow stage '${stage.id}' references non-existent role '${roleId}'`);
223
+ }
224
+ }
225
+ }
226
+ if (stage.autoAssign?.roles) {
227
+ for (const roleId of stage.autoAssign.roles) {
228
+ if (!allRoleIds.has(roleId)) {
229
+ throw new Error(
230
+ `Workflow stage '${stage.id}' autoAssign references non-existent role '${roleId}'`
231
+ );
232
+ }
233
+ }
234
+ }
235
+ if (stage.escalation) {
236
+ for (const roleId of stage.escalation.notifyRoles ?? []) {
237
+ if (!allRoleIds.has(roleId)) {
238
+ throw new Error(
239
+ `Workflow stage '${stage.id}' escalation.notifyRoles references non-existent role '${roleId}'`
240
+ );
241
+ }
242
+ }
243
+ for (const roleId of stage.escalation.escalateToRoles ?? []) {
244
+ if (!allRoleIds.has(roleId)) {
245
+ throw new Error(
246
+ `Workflow stage '${stage.id}' escalation.escalateToRoles references non-existent role '${roleId}'`
247
+ );
248
+ }
249
+ }
250
+ }
251
+ }
252
+ }
253
+ if (config.views && config.views.length > 0) {
254
+ const viewIds = /* @__PURE__ */ new Set();
255
+ for (const view of config.views) {
256
+ if (viewIds.has(view.id)) {
257
+ throw new Error(`Duplicate view ID '${view.id}'`);
258
+ }
259
+ viewIds.add(view.id);
260
+ }
261
+ }
262
+ return {
263
+ _tag: "schema",
264
+ ...config.locales && config.locales.length > 0 && { locales: config.locales },
265
+ contentTypes: config.contentTypes,
266
+ components: config.components ?? {},
267
+ singletonContentTypes: config.singletonContentTypes ?? {},
268
+ queries: config.queries ?? {},
269
+ settingsGroups: config.settingsGroups,
270
+ ...config.assetTypes && { assetTypes: config.assetTypes },
271
+ ...config.roles && config.roles.length > 0 && { roles: config.roles },
272
+ ...config.workflow && { workflow: config.workflow },
273
+ ...config.views && config.views.length > 0 && { views: config.views }
274
+ };
275
+ }
276
+ __name(defineSchema, "defineSchema");
277
+ function schemaToJSON(schema) {
278
+ const stripTag = /* @__PURE__ */ __name((obj) => {
279
+ const { _tag, ...rest } = obj;
280
+ return rest;
281
+ }, "stripTag");
282
+ return {
283
+ // Include locales if defined (strip _tag from each locale)
284
+ ...schema.locales && schema.locales.length > 0 && {
285
+ locales: schema.locales.map((locale) => stripTag(locale))
286
+ },
287
+ contentTypes: Object.fromEntries(
288
+ Object.entries(schema.contentTypes).map(([key, value]) => [key, stripTag(value)])
289
+ ),
290
+ components: Object.fromEntries(
291
+ Object.entries(schema.components).map(([key, value]) => [key, stripTag(value)])
292
+ ),
293
+ singletonContentTypes: Object.fromEntries(
294
+ Object.entries(schema.singletonContentTypes).map(([key, value]) => [key, stripTag(value)])
295
+ ),
296
+ queries: Object.fromEntries(
297
+ Object.entries(schema.queries).map(([key, value]) => [key, stripTag(value)])
298
+ ),
299
+ ...schema.settingsGroups && {
300
+ settingsGroups: Object.fromEntries(
301
+ Object.entries(schema.settingsGroups).map(([key, value]) => [key, stripTag(value)])
302
+ )
303
+ },
304
+ ...schema.assetTypes && Object.keys(schema.assetTypes).length > 0 && {
305
+ assetTypes: Object.fromEntries(
306
+ Object.entries(schema.assetTypes).map(([key, value]) => [key, stripTag(value)])
307
+ )
308
+ },
309
+ // Include roles if defined (strip _tag from each role)
310
+ ...schema.roles && schema.roles.length > 0 && {
311
+ roles: schema.roles.map((role) => stripTag(role))
312
+ },
313
+ // Include workflow if defined (convert to JSON format)
314
+ ...schema.workflow && {
315
+ workflow: workflowToJSON(schema.workflow)
316
+ },
317
+ // Include views if defined (convert to JSON format)
318
+ ...schema.views && schema.views.length > 0 && {
319
+ views: schema.views.map((view) => viewToJSON(view))
320
+ }
321
+ };
322
+ }
323
+ __name(schemaToJSON, "schemaToJSON");
324
+
325
+ // src/schema/define-locale.ts
326
+ var BCP47_PATTERN = /^[a-z]{2}(-[A-Z]{2})?$/;
327
+ function defineLocale(code, options) {
328
+ if (!BCP47_PATTERN.test(code)) {
329
+ throw new Error(
330
+ `Invalid locale code '${code}'. Expected BCP 47 format: 'xx' or 'xx-XX' (e.g., 'en', 'en-US', 'fr-FR')`
331
+ );
332
+ }
333
+ if (!options.displayName || options.displayName.trim().length === 0) {
334
+ throw new Error(`Locale '${code}' requires a displayName`);
335
+ }
336
+ if (options.fallback) {
337
+ for (const fallbackCode of options.fallback) {
338
+ if (typeof fallbackCode !== "string" || !BCP47_PATTERN.test(fallbackCode)) {
339
+ throw new Error(
340
+ `Invalid fallback locale code '${fallbackCode}' in locale '${code}'. Expected BCP 47 format.`
341
+ );
342
+ }
343
+ if (fallbackCode === code) {
344
+ throw new Error(`Locale '${code}' cannot reference itself in fallback chain`);
345
+ }
346
+ }
347
+ }
348
+ return {
349
+ _tag: "locale",
350
+ code,
351
+ displayName: options.displayName,
352
+ ...options.default !== void 0 && { default: options.default },
353
+ ...options.fallback && options.fallback.length > 0 && { fallback: options.fallback },
354
+ ...options.direction && options.direction !== "ltr" && { direction: options.direction },
355
+ ...options.active !== void 0 && options.active !== true && { active: options.active }
356
+ };
357
+ }
358
+ __name(defineLocale, "defineLocale");
359
+ function isLocaleDefinition(value) {
360
+ return typeof value === "object" && value !== null && "_tag" in value && value._tag === "locale";
361
+ }
362
+ __name(isLocaleDefinition, "isLocaleDefinition");
363
+ function getLocaleCodes(locales) {
364
+ return locales.map((l) => l.code);
365
+ }
366
+ __name(getLocaleCodes, "getLocaleCodes");
367
+ function findDefaultLocale(locales) {
368
+ return locales.find((l) => l.default === true);
369
+ }
370
+ __name(findDefaultLocale, "findDefaultLocale");
371
+ function getActiveLocales(locales) {
372
+ return locales.filter((l) => l.active !== false);
373
+ }
374
+ __name(getActiveLocales, "getActiveLocales");
375
+ function buildFallbackChain(localeCode, locales, maxDepth = 10) {
376
+ const localeMap = new Map(locales.map((l) => [l.code, l]));
377
+ const chain = [];
378
+ const visited = /* @__PURE__ */ new Set();
379
+ function addFallbacks(code, depth) {
380
+ if (depth > maxDepth || visited.has(code)) return;
381
+ const locale = localeMap.get(code);
382
+ if (!locale?.fallback) return;
383
+ visited.add(code);
384
+ for (const fallbackCode of locale.fallback) {
385
+ if (!chain.includes(fallbackCode) && fallbackCode !== localeCode) {
386
+ chain.push(fallbackCode);
387
+ addFallbacks(fallbackCode, depth + 1);
388
+ }
389
+ }
390
+ }
391
+ __name(addFallbacks, "addFallbacks");
392
+ addFallbacks(localeCode, 0);
393
+ return chain;
394
+ }
395
+ __name(buildFallbackChain, "buildFallbackChain");
396
+
397
+ // src/schema/define-content-type.ts
398
+ function fieldset(id, config) {
399
+ return {
400
+ id,
401
+ displayName: config.displayName,
402
+ description: config.description,
403
+ ai: config.ai,
404
+ fields: config.fields
405
+ };
406
+ }
407
+ __name(fieldset, "fieldset");
408
+ function defineContentType(name, config) {
409
+ const base = {
410
+ _tag: "contentType",
411
+ name,
412
+ displayName: config.displayName,
413
+ displayNamePlural: config.displayNamePlural,
414
+ description: config.description,
415
+ ai: config.ai,
416
+ displayField: config.displayField,
417
+ hierarchical: config.hierarchical ?? false,
418
+ ...config.accessTags !== void 0 && config.accessTags.length > 0 && { accessTags: config.accessTags },
419
+ ...config.workflow !== void 0 && { workflow: config.workflow }
420
+ };
421
+ if ("fields" in config && config.fields) {
422
+ return { ...base, fields: config.fields };
423
+ }
424
+ if ("fieldsets" in config && config.fieldsets) {
425
+ return { ...base, fieldsets: config.fieldsets };
426
+ }
427
+ throw new Error("Content type must have either fields or fieldsets");
428
+ }
429
+ __name(defineContentType, "defineContentType");
430
+
431
+ // src/schema/define-singleton.ts
432
+ function defineSingletonContentType(name, config) {
433
+ const base = {
434
+ _tag: "singletonContentType",
435
+ name,
436
+ displayName: config.displayName,
437
+ displayNamePlural: config.displayNamePlural,
438
+ description: config.description,
439
+ ai: config.ai,
440
+ displayField: config.displayField,
441
+ hierarchical: false,
442
+ ...config.accessTags !== void 0 && config.accessTags.length > 0 && { accessTags: config.accessTags }
443
+ };
444
+ if ("fields" in config && config.fields) {
445
+ return { ...base, fields: config.fields };
446
+ }
447
+ if ("fieldsets" in config && config.fieldsets) {
448
+ return { ...base, fieldsets: config.fieldsets };
449
+ }
450
+ throw new Error("Singleton content type must have either fields or fieldsets");
451
+ }
452
+ __name(defineSingletonContentType, "defineSingletonContentType");
453
+ var defineSingleton = defineSingletonContentType;
454
+
455
+ // src/schema/define-component.ts
456
+ function defineComponent(name, config) {
457
+ return {
458
+ _tag: "component",
459
+ name,
460
+ displayName: config.displayName,
461
+ description: config.description,
462
+ ai: config.ai,
463
+ deprecated: config.deprecated ?? false,
464
+ fields: config.fields,
465
+ metadata: config.metadata
466
+ };
467
+ }
468
+ __name(defineComponent, "defineComponent");
469
+
470
+ // src/schema/define-settings-group.ts
471
+ function defineSettingsGroup(name, config) {
472
+ return {
473
+ _tag: "settingsGroup",
474
+ name,
475
+ displayName: config.displayName,
476
+ description: config.description,
477
+ ai: config.ai,
478
+ ...config.accessTags !== void 0 && config.accessTags.length > 0 && { accessTags: config.accessTags },
479
+ fields: config.fields
480
+ };
481
+ }
482
+ __name(defineSettingsGroup, "defineSettingsGroup");
483
+
484
+ // src/schema/define-asset-type.ts
485
+ function defineAssetType(name, config) {
486
+ const kindKeys = ["image", "video", "file"].filter((k) => config[k] !== void 0);
487
+ if (kindKeys.length === 0) {
488
+ throw new Error(`Asset type '${name}' must declare exactly one kind key: image, video, or file`);
489
+ }
490
+ if (kindKeys.length > 1) {
491
+ throw new Error(
492
+ `Asset type '${name}' declares multiple kind keys (${kindKeys.join(", ")}); exactly one is allowed`
493
+ );
494
+ }
495
+ const base = {
496
+ _tag: "assetType",
497
+ name,
498
+ displayName: config.displayName,
499
+ displayNamePlural: config.displayNamePlural,
500
+ description: config.description,
501
+ ai: config.ai,
502
+ displayField: config.displayField,
503
+ ...config.accessTags !== void 0 && config.accessTags.length > 0 && { accessTags: config.accessTags },
504
+ ...config.workflow !== void 0 && { workflow: config.workflow },
505
+ ...config.image !== void 0 && { image: config.image },
506
+ ...config.video !== void 0 && { video: config.video },
507
+ ...config.file !== void 0 && { file: config.file }
508
+ };
509
+ if ("fields" in config && config.fields) {
510
+ return { ...base, fields: config.fields };
511
+ }
512
+ if ("fieldsets" in config && config.fieldsets) {
513
+ return { ...base, fieldsets: config.fieldsets };
514
+ }
515
+ throw new Error(`Asset type '${name}' must have either fields or fieldsets`);
516
+ }
517
+ __name(defineAssetType, "defineAssetType");
518
+
519
+ // src/schema/define-role.ts
520
+ var BUILT_IN_ROLES = ["admin", "editor", "viewer"];
521
+ var ROLE_ACTIONS = [
522
+ "create",
523
+ "read",
524
+ "update",
525
+ "delete",
526
+ "publish",
527
+ "unpublish",
528
+ "duplicate",
529
+ "comment",
530
+ "approveElevated"
531
+ ];
532
+ var BUILT_IN_ROLE_ACTIONS = {
533
+ admin: ["create", "read", "update", "delete", "publish", "unpublish", "duplicate", "comment"],
534
+ editor: ["create", "read", "update", "delete", "publish", "unpublish", "duplicate", "comment"],
535
+ viewer: ["read", "comment"]
536
+ };
537
+ function defineRole(id, config) {
538
+ if (!id || id.length === 0) {
539
+ throw new Error("Role ID is required");
540
+ }
541
+ const roleIdPattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$|^[a-z][a-zA-Z0-9]*$/;
542
+ if (!roleIdPattern.test(id)) {
543
+ throw new Error(
544
+ `Role ID '${id}' must be kebab-case (e.g., blog-editor) or camelCase (e.g., blogEditor)`
545
+ );
546
+ }
547
+ if (BUILT_IN_ROLES.includes(id)) {
548
+ throw new Error(`Role ID '${id}' cannot use a built-in role name (admin, editor, viewer)`);
549
+ }
550
+ if (!config.displayName || config.displayName.length === 0) {
551
+ throw new Error("Role displayName is required");
552
+ }
553
+ const hasBaseRole = config.baseRole !== void 0;
554
+ const hasIncludes = Array.isArray(config.includes) && config.includes.length > 0;
555
+ const hasPermissions = Array.isArray(config.permissions) && config.permissions.length > 0;
556
+ const hasHiddenFields = config.fields !== void 0 && Array.isArray(config.fields.hidden) && config.fields.hidden.length > 0;
557
+ const hasReadonlyFields = config.fields !== void 0 && Array.isArray(config.fields.readonly) && config.fields.readonly.length > 0;
558
+ const hasFields = hasHiddenFields || hasReadonlyFields;
559
+ if (!hasBaseRole && !hasIncludes && !hasPermissions && !hasFields) {
560
+ throw new Error(
561
+ `Role '${id}' must have at least one of: 'baseRole', 'includes', or permissions (with tags/actions or fields)`
562
+ );
563
+ }
564
+ if (Array.isArray(config.permissions) && config.permissions.length > 0) {
565
+ for (const perm of config.permissions) {
566
+ if (perm.tags.length === 0) {
567
+ throw new Error(`Permission in role '${id}' must have at least one tag`);
568
+ }
569
+ if (perm.actions.length === 0) {
570
+ throw new Error(`Permission in role '${id}' must have at least one action`);
571
+ }
572
+ for (const action of perm.actions) {
573
+ if (!ROLE_ACTIONS.includes(action)) {
574
+ throw new Error(
575
+ `Invalid action '${action}' in role '${id}'. Valid actions: ${ROLE_ACTIONS.join(", ")}`
576
+ );
577
+ }
578
+ }
579
+ }
580
+ }
581
+ return {
582
+ _tag: "role",
583
+ id,
584
+ displayName: config.displayName,
585
+ ...config.description !== void 0 && config.description !== "" && { description: config.description },
586
+ ...config.baseRole !== void 0 && { baseRole: config.baseRole },
587
+ ...hasIncludes && { includes: config.includes },
588
+ ...hasPermissions && { permissions: config.permissions },
589
+ ...config.fields !== void 0 && { fields: config.fields }
590
+ };
591
+ }
592
+ __name(defineRole, "defineRole");
593
+ function isRoleDefinition(value) {
594
+ return typeof value === "object" && value !== null && "_tag" in value && value._tag === "role";
595
+ }
596
+ __name(isRoleDefinition, "isRoleDefinition");
597
+ function isBuiltInRole(roleId) {
598
+ return BUILT_IN_ROLES.includes(roleId);
599
+ }
600
+ __name(isBuiltInRole, "isBuiltInRole");
601
+ function getBuiltInRoleActions(roleId) {
602
+ return BUILT_IN_ROLE_ACTIONS[roleId];
603
+ }
604
+ __name(getBuiltInRoleActions, "getBuiltInRoleActions");
605
+
606
+ // src/schema/define-query.ts
607
+ function defineQuery(name, config) {
608
+ if (!config.fetch && !config.aggregate && !config.search && !config.similar) {
609
+ throw new Error("Query must have at least one of: fetch, aggregate, search, or similar");
610
+ }
611
+ if (!config.endpoint.startsWith("/api/")) {
612
+ throw new Error("Query endpoint must start with /api/");
613
+ }
614
+ return {
615
+ _tag: "query",
616
+ name,
617
+ endpoint: config.endpoint,
618
+ description: config.description,
619
+ fetch: config.fetch,
620
+ aggregate: config.aggregate,
621
+ search: config.search,
622
+ similar: config.similar,
623
+ include: config.include,
624
+ filters: config.filters,
625
+ select: config.select,
626
+ cache: config.cache
627
+ };
628
+ }
629
+ __name(defineQuery, "defineQuery");
630
+
631
+ // src/schema/fields/index.ts
632
+ var fields_exports = {};
633
+ __export(fields_exports, {
634
+ boolean: () => boolean,
635
+ component: () => component,
636
+ date: () => date,
637
+ dateTime: () => dateTime,
638
+ decimal: () => decimal,
639
+ email: () => email,
640
+ enum: () => enumField,
641
+ integer: () => integer,
642
+ list: () => list,
643
+ longText: () => longText,
644
+ reference: () => reference,
645
+ richText: () => richText,
646
+ shortText: () => shortText,
647
+ slug: () => slug,
648
+ tags: () => tags,
649
+ url: () => url
650
+ });
651
+
652
+ // src/schema/fields/builders.ts
653
+ function createField(id, type, options = {}) {
654
+ return {
655
+ id,
656
+ type,
657
+ ...options.config !== void 0 && { config: options.config },
658
+ ...options.ui !== void 0 && { ui: options.ui },
659
+ ...options.ai !== void 0 && { ai: options.ai },
660
+ ...options.rules !== void 0 && options.rules.length > 0 && { rules: options.rules },
661
+ ...options.localization !== void 0 && { localization: options.localization },
662
+ ...options.fallback !== void 0 && { fallback: options.fallback },
663
+ ...options.deprecated !== void 0 && { deprecated: options.deprecated }
664
+ };
665
+ }
666
+ __name(createField, "createField");
667
+ function shortText(id, options = {}) {
668
+ return createField(id, "shortText", options);
669
+ }
670
+ __name(shortText, "shortText");
671
+ function longText(id, options = {}) {
672
+ return createField(id, "longText", options);
673
+ }
674
+ __name(longText, "longText");
675
+ function richText(id, options = {}) {
676
+ return createField(id, "richText", options);
677
+ }
678
+ __name(richText, "richText");
679
+ function slug(id, options = {}) {
680
+ return createField(id, "slug", options);
681
+ }
682
+ __name(slug, "slug");
683
+ function url(id, options = {}) {
684
+ return createField(id, "url", options);
685
+ }
686
+ __name(url, "url");
687
+ function email(id, options = {}) {
688
+ return createField(id, "email", options);
689
+ }
690
+ __name(email, "email");
691
+ function integer(id, options = {}) {
692
+ return createField(id, "integer", options);
693
+ }
694
+ __name(integer, "integer");
695
+ function decimal(id, options = {}) {
696
+ return createField(id, "decimal", options);
697
+ }
698
+ __name(decimal, "decimal");
699
+ function boolean(id, options = {}) {
700
+ return createField(id, "boolean", options);
701
+ }
702
+ __name(boolean, "boolean");
703
+ function enumField(id, options = {}) {
704
+ return createField(id, "enum", options);
705
+ }
706
+ __name(enumField, "enumField");
707
+ function date(id, options = {}) {
708
+ return createField(id, "date", options);
709
+ }
710
+ __name(date, "date");
711
+ function dateTime(id, options = {}) {
712
+ return createField(id, "dateTime", options);
713
+ }
714
+ __name(dateTime, "dateTime");
715
+ function reference(id, options = {}) {
716
+ return createField(id, "reference", options);
717
+ }
718
+ __name(reference, "reference");
719
+ function tags(id, options = {}) {
720
+ return createField(id, "tags", options);
721
+ }
722
+ __name(tags, "tags");
723
+ function list(id, options = {}) {
724
+ return createField(id, "list", options);
725
+ }
726
+ __name(list, "list");
727
+ function component(id, componentId, options = {}) {
728
+ const type = `component(${componentId})`;
729
+ return createField(id, type, options);
730
+ }
731
+ __name(component, "component");
732
+
733
+ // src/schema/index.ts
734
+ var fields = fields_exports;
735
+
736
+ export { BUILT_IN_ROLES, BUILT_IN_ROLE_ACTIONS, ROLE_ACTIONS, buildFallbackChain, defineAssetType, defineComponent, defineContentType, defineContentTypeWorkflow, defineLocale, defineQuery, defineRole, defineSchema, defineSettingsGroup, defineSingleton, defineSingletonContentType, defineView, defineWorkflow, defineWorkflowStage, fields, fieldset, findDefaultLocale, findWorkflowStage, getActiveLocales, getBuiltInRoleActions, getFirstWorkflowStage, getLocaleCodes, getNextWorkflowStage, getWorkflowStageIds, isBuiltInRole, isFinalWorkflowStage, isLocaleDefinition, isRoleDefinition, isWorkflowDefinition, isWorkflowStageDefinition, schemaToJSON, viewToJSON, workflowToJSON };
737
+ //# sourceMappingURL=chunk-2QUK2ZGD.js.map
738
+ //# sourceMappingURL=chunk-2QUK2ZGD.js.map