@betterstart/cli 0.1.3 → 0.1.5
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/README.md +133 -0
- package/dist/cli.d.ts +1 -9
- package/dist/cli.js +13585 -367
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +24 -266
- package/dist/index.js +4 -11378
- package/dist/index.js.map +1 -1
- package/package.json +29 -42
- package/templates/schema.json +959 -0
- package/templates/tiptap/hooks/use-composed-ref.ts +43 -0
- package/templates/tiptap/hooks/use-cursor-visibility.ts +68 -0
- package/templates/tiptap/hooks/use-element-rect.ts +166 -0
- package/templates/tiptap/hooks/use-is-breakpoint.ts +32 -0
- package/templates/tiptap/hooks/use-menu-navigation.ts +182 -0
- package/templates/tiptap/hooks/use-scrolling.ts +64 -0
- package/templates/tiptap/hooks/use-throttled-callback.ts +146 -0
- package/templates/tiptap/hooks/use-tiptap-editor.ts +46 -0
- package/templates/tiptap/hooks/use-unmount.ts +21 -0
- package/templates/tiptap/hooks/use-window-size.ts +87 -0
- package/templates/tiptap/lib/tiptap-utils.ts +587 -0
- package/templates/tiptap/styles/_keyframe-animations.scss +91 -0
- package/templates/tiptap/styles/_variables.scss +296 -0
- package/templates/tiptap/tiptap-extension/node-background-extension.ts +138 -0
- package/templates/tiptap/tiptap-icons/align-center-icon.tsx +38 -0
- package/templates/tiptap/tiptap-icons/align-justify-icon.tsx +38 -0
- package/templates/tiptap/tiptap-icons/align-left-icon.tsx +38 -0
- package/templates/tiptap/tiptap-icons/align-right-icon.tsx +38 -0
- package/templates/tiptap/tiptap-icons/arrow-left-icon.tsx +24 -0
- package/templates/tiptap/tiptap-icons/ban-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/blockquote-icon.tsx +44 -0
- package/templates/tiptap/tiptap-icons/bold-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/chevron-down-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/close-icon.tsx +24 -0
- package/templates/tiptap/tiptap-icons/code-block-icon.tsx +38 -0
- package/templates/tiptap/tiptap-icons/code2-icon.tsx +32 -0
- package/templates/tiptap/tiptap-icons/corner-down-left-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/external-link-icon.tsx +28 -0
- package/templates/tiptap/tiptap-icons/heading-five-icon.tsx +28 -0
- package/templates/tiptap/tiptap-icons/heading-four-icon.tsx +28 -0
- package/templates/tiptap/tiptap-icons/heading-icon.tsx +24 -0
- package/templates/tiptap/tiptap-icons/heading-one-icon.tsx +28 -0
- package/templates/tiptap/tiptap-icons/heading-six-icon.tsx +30 -0
- package/templates/tiptap/tiptap-icons/heading-three-icon.tsx +36 -0
- package/templates/tiptap/tiptap-icons/heading-two-icon.tsx +28 -0
- package/templates/tiptap/tiptap-icons/highlighter-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/image-plus-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/italic-icon.tsx +24 -0
- package/templates/tiptap/tiptap-icons/link-icon.tsx +28 -0
- package/templates/tiptap/tiptap-icons/list-icon.tsx +56 -0
- package/templates/tiptap/tiptap-icons/list-ordered-icon.tsx +56 -0
- package/templates/tiptap/tiptap-icons/list-todo-icon.tsx +50 -0
- package/templates/tiptap/tiptap-icons/moon-star-icon.tsx +30 -0
- package/templates/tiptap/tiptap-icons/redo2-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/strike-icon.tsx +28 -0
- package/templates/tiptap/tiptap-icons/subscript-icon.tsx +38 -0
- package/templates/tiptap/tiptap-icons/sun-icon.tsx +58 -0
- package/templates/tiptap/tiptap-icons/superscript-icon.tsx +38 -0
- package/templates/tiptap/tiptap-icons/trash-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/underline-icon.tsx +26 -0
- package/templates/tiptap/tiptap-icons/undo2-icon.tsx +26 -0
- package/templates/tiptap/tiptap-node/blockquote-node/blockquote-node.scss +37 -0
- package/templates/tiptap/tiptap-node/code-block-node/code-block-node.scss +54 -0
- package/templates/tiptap/tiptap-node/heading-node/heading-node.scss +45 -0
- package/templates/tiptap/tiptap-node/horizontal-rule-node/horizontal-rule-node-extension.ts +10 -0
- package/templates/tiptap/tiptap-node/horizontal-rule-node/horizontal-rule-node.scss +25 -0
- package/templates/tiptap/tiptap-node/image-node/image-node.scss +35 -0
- package/templates/tiptap/tiptap-node/image-upload-node/image-upload-node-extension.ts +154 -0
- package/templates/tiptap/tiptap-node/image-upload-node/image-upload-node.scss +249 -0
- package/templates/tiptap/tiptap-node/image-upload-node/image-upload-node.tsx +522 -0
- package/templates/tiptap/tiptap-node/image-upload-node/index.tsx +1 -0
- package/templates/tiptap/tiptap-node/list-node/list-node.scss +208 -0
- package/templates/tiptap/tiptap-node/paragraph-node/paragraph-node.scss +273 -0
- package/templates/tiptap/tiptap-ui/blockquote-button/blockquote-button.tsx +104 -0
- package/templates/tiptap/tiptap-ui/blockquote-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/blockquote-button/use-blockquote.ts +252 -0
- package/templates/tiptap/tiptap-ui/code-block-button/code-block-button.tsx +106 -0
- package/templates/tiptap/tiptap-ui/code-block-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/code-block-button/use-code-block.ts +261 -0
- package/templates/tiptap/tiptap-ui/color-highlight-button/color-highlight-button.scss +49 -0
- package/templates/tiptap/tiptap-ui/color-highlight-button/color-highlight-button.tsx +153 -0
- package/templates/tiptap/tiptap-ui/color-highlight-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/color-highlight-button/use-color-highlight.ts +345 -0
- package/templates/tiptap/tiptap-ui/color-highlight-popover/color-highlight-popover.tsx +207 -0
- package/templates/tiptap/tiptap-ui/color-highlight-popover/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui/heading-button/heading-button.tsx +107 -0
- package/templates/tiptap/tiptap-ui/heading-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/heading-button/use-heading.ts +314 -0
- package/templates/tiptap/tiptap-ui/heading-dropdown-menu/heading-dropdown-menu.tsx +131 -0
- package/templates/tiptap/tiptap-ui/heading-dropdown-menu/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/heading-dropdown-menu/use-heading-dropdown-menu.ts +130 -0
- package/templates/tiptap/tiptap-ui/image-upload-button/image-upload-button.tsx +114 -0
- package/templates/tiptap/tiptap-ui/image-upload-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/image-upload-button/use-image-upload.ts +192 -0
- package/templates/tiptap/tiptap-ui/link-popover/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/link-popover/link-popover.tsx +285 -0
- package/templates/tiptap/tiptap-ui/link-popover/use-link-popover.ts +286 -0
- package/templates/tiptap/tiptap-ui/list-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/list-button/list-button.tsx +108 -0
- package/templates/tiptap/tiptap-ui/list-button/use-list.ts +329 -0
- package/templates/tiptap/tiptap-ui/list-dropdown-menu/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui/list-dropdown-menu/list-dropdown-menu.tsx +123 -0
- package/templates/tiptap/tiptap-ui/list-dropdown-menu/use-list-dropdown-menu.ts +203 -0
- package/templates/tiptap/tiptap-ui/mark-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/mark-button/mark-button.tsx +107 -0
- package/templates/tiptap/tiptap-ui/mark-button/use-mark.ts +206 -0
- package/templates/tiptap/tiptap-ui/text-align-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/text-align-button/text-align-button.tsx +118 -0
- package/templates/tiptap/tiptap-ui/text-align-button/use-text-align.ts +212 -0
- package/templates/tiptap/tiptap-ui/undo-redo-button/index.tsx +2 -0
- package/templates/tiptap/tiptap-ui/undo-redo-button/undo-redo-button.tsx +105 -0
- package/templates/tiptap/tiptap-ui/undo-redo-button/use-undo-redo.ts +173 -0
- package/templates/tiptap/tiptap-ui-primitive/badge/badge-colors.scss +395 -0
- package/templates/tiptap/tiptap-ui-primitive/badge/badge-group.scss +16 -0
- package/templates/tiptap/tiptap-ui-primitive/badge/badge.scss +99 -0
- package/templates/tiptap/tiptap-ui-primitive/badge/badge.tsx +46 -0
- package/templates/tiptap/tiptap-ui-primitive/badge/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/button/button-colors.scss +429 -0
- package/templates/tiptap/tiptap-ui-primitive/button/button-group.scss +22 -0
- package/templates/tiptap/tiptap-ui-primitive/button/button.scss +314 -0
- package/templates/tiptap/tiptap-ui-primitive/button/button.tsx +102 -0
- package/templates/tiptap/tiptap-ui-primitive/button/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/card/card.scss +77 -0
- package/templates/tiptap/tiptap-ui-primitive/card/card.tsx +59 -0
- package/templates/tiptap/tiptap-ui-primitive/card/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/dropdown-menu/dropdown-menu.scss +63 -0
- package/templates/tiptap/tiptap-ui-primitive/dropdown-menu/dropdown-menu.tsx +95 -0
- package/templates/tiptap/tiptap-ui-primitive/dropdown-menu/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/input/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/input/input.scss +45 -0
- package/templates/tiptap/tiptap-ui-primitive/input/input.tsx +18 -0
- package/templates/tiptap/tiptap-ui-primitive/popover/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/popover/popover.scss +63 -0
- package/templates/tiptap/tiptap-ui-primitive/popover/popover.tsx +33 -0
- package/templates/tiptap/tiptap-ui-primitive/separator/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/separator/separator.scss +23 -0
- package/templates/tiptap/tiptap-ui-primitive/separator/separator.tsx +33 -0
- package/templates/tiptap/tiptap-ui-primitive/spacer/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/spacer/spacer.tsx +21 -0
- package/templates/tiptap/tiptap-ui-primitive/toolbar/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/toolbar/toolbar.scss +98 -0
- package/templates/tiptap/tiptap-ui-primitive/toolbar/toolbar.tsx +113 -0
- package/templates/tiptap/tiptap-ui-primitive/tooltip/index.tsx +1 -0
- package/templates/tiptap/tiptap-ui-primitive/tooltip/tooltip.scss +43 -0
- package/templates/tiptap/tiptap-ui-primitive/tooltip/tooltip.tsx +223 -0
- package/templates/ui/accordion.tsx +52 -0
- package/templates/ui/alert-dialog.tsx +116 -0
- package/templates/ui/alert.tsx +48 -0
- package/templates/ui/aspect-ratio.tsx +7 -0
- package/templates/ui/avatar.tsx +46 -0
- package/templates/ui/badge.tsx +32 -0
- package/templates/ui/breadcrumb.tsx +98 -0
- package/templates/ui/button-group.tsx +77 -0
- package/templates/ui/button.tsx +48 -0
- package/templates/ui/calendar.tsx +176 -0
- package/templates/ui/card.tsx +54 -0
- package/templates/ui/carousel.tsx +234 -0
- package/templates/ui/chart.tsx +349 -0
- package/templates/ui/checkbox.tsx +27 -0
- package/templates/ui/collapsible.tsx +11 -0
- package/templates/ui/command.tsx +142 -0
- package/templates/ui/context-menu.tsx +188 -0
- package/templates/ui/curriculum-editor.tsx +601 -0
- package/templates/ui/date-picker.tsx +70 -0
- package/templates/ui/dialog.tsx +103 -0
- package/templates/ui/drawer.tsx +99 -0
- package/templates/ui/dropdown-menu.tsx +185 -0
- package/templates/ui/dynamic-list-field.tsx +95 -0
- package/templates/ui/empty.tsx +90 -0
- package/templates/ui/field.tsx +231 -0
- package/templates/ui/file-upload-example.tsx +113 -0
- package/templates/ui/form.tsx +172 -0
- package/templates/ui/hover-card.tsx +28 -0
- package/templates/ui/icon-picker.tsx +435 -0
- package/templates/ui/icons-data.ts +6 -0
- package/templates/ui/image-upload-field.tsx +360 -0
- package/templates/ui/input-group.tsx +160 -0
- package/templates/ui/input-otp.tsx +70 -0
- package/templates/ui/input.tsx +21 -0
- package/templates/ui/item.tsx +171 -0
- package/templates/ui/kbd.tsx +28 -0
- package/templates/ui/label.tsx +20 -0
- package/templates/ui/logo.tsx +113 -0
- package/templates/ui/markdown-editor.tsx +303 -0
- package/templates/ui/markdown-utils.ts +128 -0
- package/templates/ui/media-upload-field.tsx +255 -0
- package/templates/ui/menubar.tsx +230 -0
- package/templates/ui/navigation-menu.tsx +119 -0
- package/templates/ui/pagination.tsx +96 -0
- package/templates/ui/placeholder.tsx +25 -0
- package/templates/ui/popover.tsx +32 -0
- package/templates/ui/progress.tsx +24 -0
- package/templates/ui/radio-group.tsx +37 -0
- package/templates/ui/resizable.tsx +41 -0
- package/templates/ui/rich-text-editor.tsx +374 -0
- package/templates/ui/scroll-area.tsx +45 -0
- package/templates/ui/select.tsx +151 -0
- package/templates/ui/separator.tsx +25 -0
- package/templates/ui/sheet.tsx +120 -0
- package/templates/ui/sidebar.tsx +687 -0
- package/templates/ui/skeleton.tsx +7 -0
- package/templates/ui/slider.tsx +24 -0
- package/templates/ui/sonner.tsx +29 -0
- package/templates/ui/spinner.tsx +15 -0
- package/templates/ui/switch.tsx +28 -0
- package/templates/ui/table.tsx +93 -0
- package/templates/ui/tabs.tsx +54 -0
- package/templates/ui/textarea.tsx +20 -0
- package/templates/ui/toast.tsx +127 -0
- package/templates/ui/toggle-group.tsx +56 -0
- package/templates/ui/toggle.tsx +43 -0
- package/templates/ui/tooltip.tsx +31 -0
- package/templates/ui/use-mobile.tsx +19 -0
- package/templates/ui/video-upload-field.tsx +368 -0
- package/dist/chunk-EIH4RRIJ.js +0 -183
- package/dist/chunk-EIH4RRIJ.js.map +0 -1
- package/dist/chunk-NKRQYAS6.js +0 -260
- package/dist/chunk-NKRQYAS6.js.map +0 -1
- package/dist/chunk-QLVSHP7X.js +0 -235
- package/dist/chunk-QLVSHP7X.js.map +0 -1
- package/dist/chunk-WY6BC55D.js +0 -357
- package/dist/chunk-WY6BC55D.js.map +0 -1
- package/dist/config/index.d.ts +0 -93
- package/dist/config/index.js +0 -58
- package/dist/config/index.js.map +0 -1
- package/dist/core/index.d.ts +0 -415
- package/dist/core/index.js +0 -906
- package/dist/core/index.js.map +0 -1
- package/dist/import-resolver-BaZ-rzkH.d.ts +0 -123
- package/dist/logger-awLb347n.d.ts +0 -81
- package/dist/plugins/index.d.ts +0 -213
- package/dist/plugins/index.js +0 -365
- package/dist/plugins/index.js.map +0 -1
- package/dist/types-ByX_gl6y.d.ts +0 -232
- package/dist/types-eI549DEG.d.ts +0 -331
|
@@ -0,0 +1,959 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://betterstart.dev/schemas/schema.json",
|
|
4
|
+
"title": "BetterStart Schema Definition",
|
|
5
|
+
"description": "JSON Schema for validating custom schema files (courses.json, testimonials.json, instructors.json, events.json, etc.)",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["name", "label", "fields"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"$schema": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description": "JSON Schema reference (typically './schema.json')"
|
|
13
|
+
},
|
|
14
|
+
"name": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"description": "Unique identifier for the schema (e.g., 'courses', 'site-settings')",
|
|
17
|
+
"pattern": "^[a-z][a-zA-Z0-9-]*$"
|
|
18
|
+
},
|
|
19
|
+
"label": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "Human-readable display name for the schema"
|
|
22
|
+
},
|
|
23
|
+
"description": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"description": "Brief description of what this schema represents"
|
|
26
|
+
},
|
|
27
|
+
"icon": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"description": "Icon name from the icon library (e.g., 'BookOpen', 'Package')"
|
|
30
|
+
},
|
|
31
|
+
"type": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"description": "Schema type: 'entity' for CRUD list (default), 'single' for singleton record (site settings, about page), 'github' for GitHub-synced content",
|
|
34
|
+
"enum": ["entity", "single", "github"]
|
|
35
|
+
},
|
|
36
|
+
"username": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"description": "GitHub username or organization for GitHub-type schemas"
|
|
39
|
+
},
|
|
40
|
+
"repos": {
|
|
41
|
+
"type": "array",
|
|
42
|
+
"description": "GitHub repository configurations for syncing content",
|
|
43
|
+
"items": {
|
|
44
|
+
"$ref": "#/$defs/repoConfig"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"fields": {
|
|
48
|
+
"type": "array",
|
|
49
|
+
"description": "Array of field definitions",
|
|
50
|
+
"items": {
|
|
51
|
+
"$ref": "#/$defs/field"
|
|
52
|
+
},
|
|
53
|
+
"minItems": 1
|
|
54
|
+
},
|
|
55
|
+
"columns": {
|
|
56
|
+
"type": "array",
|
|
57
|
+
"description": "Table column definitions for list views",
|
|
58
|
+
"items": {
|
|
59
|
+
"$ref": "#/$defs/column"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"actions": {
|
|
63
|
+
"$ref": "#/$defs/actions"
|
|
64
|
+
},
|
|
65
|
+
"search": {
|
|
66
|
+
"$ref": "#/$defs/search"
|
|
67
|
+
},
|
|
68
|
+
"filters": {
|
|
69
|
+
"$ref": "#/$defs/filters"
|
|
70
|
+
},
|
|
71
|
+
"autoCategorize": {
|
|
72
|
+
"$ref": "#/$defs/autoCategorize"
|
|
73
|
+
},
|
|
74
|
+
"autoSlugify": {
|
|
75
|
+
"$ref": "#/$defs/autoSlugify"
|
|
76
|
+
},
|
|
77
|
+
"githubSyncPage": {
|
|
78
|
+
"$ref": "#/$defs/githubSyncPage"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"$defs": {
|
|
82
|
+
"field": {
|
|
83
|
+
"type": "object",
|
|
84
|
+
"description": "A field definition",
|
|
85
|
+
"oneOf": [
|
|
86
|
+
{ "$ref": "#/$defs/serialField" },
|
|
87
|
+
{ "$ref": "#/$defs/stringField" },
|
|
88
|
+
{ "$ref": "#/$defs/textField" },
|
|
89
|
+
{ "$ref": "#/$defs/markdownField" },
|
|
90
|
+
{ "$ref": "#/$defs/richtextField" },
|
|
91
|
+
{ "$ref": "#/$defs/imageField" },
|
|
92
|
+
{ "$ref": "#/$defs/dateField" },
|
|
93
|
+
{ "$ref": "#/$defs/booleanField" },
|
|
94
|
+
{ "$ref": "#/$defs/timestampField" },
|
|
95
|
+
{ "$ref": "#/$defs/numberField" },
|
|
96
|
+
{ "$ref": "#/$defs/decimalField" },
|
|
97
|
+
{ "$ref": "#/$defs/selectField" },
|
|
98
|
+
{ "$ref": "#/$defs/listField" },
|
|
99
|
+
{ "$ref": "#/$defs/groupField" },
|
|
100
|
+
{ "$ref": "#/$defs/tabsField" },
|
|
101
|
+
{ "$ref": "#/$defs/relationshipField" },
|
|
102
|
+
{ "$ref": "#/$defs/separatorField" },
|
|
103
|
+
{ "$ref": "#/$defs/videoField" },
|
|
104
|
+
{ "$ref": "#/$defs/mediaField" },
|
|
105
|
+
{ "$ref": "#/$defs/githubRepoField" },
|
|
106
|
+
{ "$ref": "#/$defs/githubBranchField" },
|
|
107
|
+
{ "$ref": "#/$defs/githubDirectoryField" },
|
|
108
|
+
{ "$ref": "#/$defs/githubChaptersField" },
|
|
109
|
+
{ "$ref": "#/$defs/curriculumField" }
|
|
110
|
+
]
|
|
111
|
+
},
|
|
112
|
+
"baseFieldProperties": {
|
|
113
|
+
"type": "object",
|
|
114
|
+
"properties": {
|
|
115
|
+
"name": {
|
|
116
|
+
"type": "string",
|
|
117
|
+
"description": "Field identifier (camelCase)",
|
|
118
|
+
"pattern": "^[a-zA-Z][a-zA-Z0-9]*$"
|
|
119
|
+
},
|
|
120
|
+
"label": {
|
|
121
|
+
"type": "string",
|
|
122
|
+
"description": "Human-readable field label"
|
|
123
|
+
},
|
|
124
|
+
"required": {
|
|
125
|
+
"type": "boolean",
|
|
126
|
+
"description": "Whether this field is required",
|
|
127
|
+
"default": false
|
|
128
|
+
},
|
|
129
|
+
"hint": {
|
|
130
|
+
"type": "string",
|
|
131
|
+
"description": "Helper text displayed below the field"
|
|
132
|
+
},
|
|
133
|
+
"showWhen": {
|
|
134
|
+
"$ref": "#/$defs/showWhenCondition"
|
|
135
|
+
},
|
|
136
|
+
"dependsOn": {
|
|
137
|
+
"$ref": "#/$defs/dependsOnCondition"
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
"dependsOnCondition": {
|
|
142
|
+
"type": "object",
|
|
143
|
+
"description": "For cascading fields - specifies which sibling field(s) this field depends on",
|
|
144
|
+
"additionalProperties": false,
|
|
145
|
+
"properties": {
|
|
146
|
+
"repo": {
|
|
147
|
+
"type": "string",
|
|
148
|
+
"description": "Name of the repo field for branch/directory selectors"
|
|
149
|
+
},
|
|
150
|
+
"branch": {
|
|
151
|
+
"type": "string",
|
|
152
|
+
"description": "Name of the branch field for directory selectors"
|
|
153
|
+
},
|
|
154
|
+
"directory": {
|
|
155
|
+
"type": "string",
|
|
156
|
+
"description": "Name of the directory field for chapters loader"
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
"showWhenCondition": {
|
|
161
|
+
"type": "object",
|
|
162
|
+
"description": "Conditional visibility based on sibling field value",
|
|
163
|
+
"required": ["field", "value"],
|
|
164
|
+
"additionalProperties": false,
|
|
165
|
+
"properties": {
|
|
166
|
+
"field": {
|
|
167
|
+
"type": "string",
|
|
168
|
+
"description": "Name of the sibling field to watch"
|
|
169
|
+
},
|
|
170
|
+
"value": {
|
|
171
|
+
"oneOf": [{ "type": "boolean" }, { "type": "string" }, { "type": "number" }],
|
|
172
|
+
"description": "Value that makes this field visible"
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
"serialField": {
|
|
177
|
+
"type": "object",
|
|
178
|
+
"description": "Auto-incrementing primary key field",
|
|
179
|
+
"required": ["name", "type"],
|
|
180
|
+
"additionalProperties": false,
|
|
181
|
+
"properties": {
|
|
182
|
+
"name": { "type": "string" },
|
|
183
|
+
"type": { "const": "serial" },
|
|
184
|
+
"primaryKey": {
|
|
185
|
+
"type": "boolean",
|
|
186
|
+
"description": "Whether this is the primary key",
|
|
187
|
+
"default": true
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
"stringField": {
|
|
192
|
+
"type": "object",
|
|
193
|
+
"description": "Single-line text input field",
|
|
194
|
+
"required": ["name", "type"],
|
|
195
|
+
"additionalProperties": false,
|
|
196
|
+
"properties": {
|
|
197
|
+
"name": { "type": "string" },
|
|
198
|
+
"type": { "const": "string" },
|
|
199
|
+
"label": { "type": "string" },
|
|
200
|
+
"required": { "type": "boolean" },
|
|
201
|
+
"length": {
|
|
202
|
+
"type": "integer",
|
|
203
|
+
"description": "Maximum character length",
|
|
204
|
+
"minimum": 1,
|
|
205
|
+
"maximum": 65535
|
|
206
|
+
},
|
|
207
|
+
"hint": { "type": "string" },
|
|
208
|
+
"placeholder": {
|
|
209
|
+
"type": "string",
|
|
210
|
+
"description": "Placeholder text displayed in the input field"
|
|
211
|
+
},
|
|
212
|
+
"default": { "type": "string" },
|
|
213
|
+
"hasIcon": {
|
|
214
|
+
"type": "boolean",
|
|
215
|
+
"description": "Whether this field has an associated icon picker"
|
|
216
|
+
},
|
|
217
|
+
"hidden": {
|
|
218
|
+
"type": "boolean",
|
|
219
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
220
|
+
},
|
|
221
|
+
"showWhen": { "$ref": "#/$defs/showWhenCondition" }
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
"textField": {
|
|
225
|
+
"type": "object",
|
|
226
|
+
"description": "Multi-line text area field",
|
|
227
|
+
"required": ["name", "type"],
|
|
228
|
+
"additionalProperties": false,
|
|
229
|
+
"properties": {
|
|
230
|
+
"name": { "type": "string" },
|
|
231
|
+
"type": { "const": "text" },
|
|
232
|
+
"label": { "type": "string" },
|
|
233
|
+
"required": { "type": "boolean" },
|
|
234
|
+
"length": {
|
|
235
|
+
"type": "integer",
|
|
236
|
+
"description": "Maximum character length",
|
|
237
|
+
"minimum": 1
|
|
238
|
+
},
|
|
239
|
+
"hint": { "type": "string" },
|
|
240
|
+
"placeholder": {
|
|
241
|
+
"type": "string",
|
|
242
|
+
"description": "Placeholder text displayed in the text area"
|
|
243
|
+
},
|
|
244
|
+
"default": { "type": "string" },
|
|
245
|
+
"hidden": {
|
|
246
|
+
"type": "boolean",
|
|
247
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
248
|
+
},
|
|
249
|
+
"showWhen": { "$ref": "#/$defs/showWhenCondition" }
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
"markdownField": {
|
|
253
|
+
"type": "object",
|
|
254
|
+
"description": "Rich text editor with markdown support",
|
|
255
|
+
"required": ["name", "type"],
|
|
256
|
+
"additionalProperties": false,
|
|
257
|
+
"properties": {
|
|
258
|
+
"name": { "type": "string" },
|
|
259
|
+
"type": { "const": "markdown" },
|
|
260
|
+
"label": { "type": "string" },
|
|
261
|
+
"required": { "type": "boolean" },
|
|
262
|
+
"hint": { "type": "string" },
|
|
263
|
+
"placeholder": {
|
|
264
|
+
"type": "string",
|
|
265
|
+
"description": "Placeholder text displayed in the markdown editor"
|
|
266
|
+
},
|
|
267
|
+
"hidden": {
|
|
268
|
+
"type": "boolean",
|
|
269
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
270
|
+
},
|
|
271
|
+
"showWhen": { "$ref": "#/$defs/showWhenCondition" }
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
"richtextField": {
|
|
275
|
+
"type": "object",
|
|
276
|
+
"description": "WYSIWYG rich text editor with markdown storage",
|
|
277
|
+
"required": ["name", "type"],
|
|
278
|
+
"additionalProperties": false,
|
|
279
|
+
"properties": {
|
|
280
|
+
"name": { "type": "string" },
|
|
281
|
+
"type": { "const": "richtext" },
|
|
282
|
+
"label": { "type": "string" },
|
|
283
|
+
"required": { "type": "boolean" },
|
|
284
|
+
"hint": { "type": "string" },
|
|
285
|
+
"placeholder": {
|
|
286
|
+
"type": "string",
|
|
287
|
+
"description": "Placeholder text displayed in the rich text editor"
|
|
288
|
+
},
|
|
289
|
+
"hidden": {
|
|
290
|
+
"type": "boolean",
|
|
291
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
292
|
+
},
|
|
293
|
+
"showWhen": { "$ref": "#/$defs/showWhenCondition" }
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
"imageField": {
|
|
297
|
+
"type": "object",
|
|
298
|
+
"description": "Image upload field",
|
|
299
|
+
"required": ["name", "type"],
|
|
300
|
+
"additionalProperties": false,
|
|
301
|
+
"properties": {
|
|
302
|
+
"name": { "type": "string" },
|
|
303
|
+
"type": { "const": "image" },
|
|
304
|
+
"label": { "type": "string" },
|
|
305
|
+
"required": { "type": "boolean" },
|
|
306
|
+
"length": {
|
|
307
|
+
"type": "integer",
|
|
308
|
+
"description": "Maximum URL length"
|
|
309
|
+
},
|
|
310
|
+
"hint": { "type": "string" },
|
|
311
|
+
"hidden": {
|
|
312
|
+
"type": "boolean",
|
|
313
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
"dateField": {
|
|
318
|
+
"type": "object",
|
|
319
|
+
"description": "Date picker field",
|
|
320
|
+
"required": ["name", "type"],
|
|
321
|
+
"additionalProperties": false,
|
|
322
|
+
"properties": {
|
|
323
|
+
"name": { "type": "string" },
|
|
324
|
+
"type": { "const": "date" },
|
|
325
|
+
"label": { "type": "string" },
|
|
326
|
+
"required": { "type": "boolean" },
|
|
327
|
+
"default": { "type": "string" },
|
|
328
|
+
"hint": { "type": "string" },
|
|
329
|
+
"hidden": {
|
|
330
|
+
"type": "boolean",
|
|
331
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
},
|
|
335
|
+
"booleanField": {
|
|
336
|
+
"type": "object",
|
|
337
|
+
"description": "Toggle/checkbox field",
|
|
338
|
+
"required": ["name", "type"],
|
|
339
|
+
"additionalProperties": false,
|
|
340
|
+
"properties": {
|
|
341
|
+
"name": { "type": "string" },
|
|
342
|
+
"type": { "const": "boolean" },
|
|
343
|
+
"label": { "type": "string" },
|
|
344
|
+
"required": { "type": "boolean" },
|
|
345
|
+
"default": { "type": "boolean" },
|
|
346
|
+
"hint": { "type": "string" },
|
|
347
|
+
"hidden": {
|
|
348
|
+
"type": "boolean",
|
|
349
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
"timestampField": {
|
|
354
|
+
"type": "object",
|
|
355
|
+
"description": "Timestamp field (typically auto-generated)",
|
|
356
|
+
"required": ["name", "type"],
|
|
357
|
+
"additionalProperties": false,
|
|
358
|
+
"properties": {
|
|
359
|
+
"name": { "type": "string" },
|
|
360
|
+
"type": { "const": "timestamp" },
|
|
361
|
+
"label": { "type": "string" },
|
|
362
|
+
"required": { "type": "boolean" },
|
|
363
|
+
"hidden": {
|
|
364
|
+
"type": "boolean",
|
|
365
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
},
|
|
369
|
+
"numberField": {
|
|
370
|
+
"type": "object",
|
|
371
|
+
"description": "Integer number input field",
|
|
372
|
+
"required": ["name", "type"],
|
|
373
|
+
"additionalProperties": false,
|
|
374
|
+
"properties": {
|
|
375
|
+
"name": { "type": "string" },
|
|
376
|
+
"type": { "const": "number" },
|
|
377
|
+
"label": { "type": "string" },
|
|
378
|
+
"required": { "type": "boolean" },
|
|
379
|
+
"default": { "type": "integer" },
|
|
380
|
+
"hint": { "type": "string" },
|
|
381
|
+
"placeholder": {
|
|
382
|
+
"type": "string",
|
|
383
|
+
"description": "Placeholder text displayed in the number input"
|
|
384
|
+
},
|
|
385
|
+
"min": { "type": "integer" },
|
|
386
|
+
"max": { "type": "integer" },
|
|
387
|
+
"hidden": {
|
|
388
|
+
"type": "boolean",
|
|
389
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
},
|
|
393
|
+
"decimalField": {
|
|
394
|
+
"type": "object",
|
|
395
|
+
"description": "Decimal number field (for prices, percentages, etc.)",
|
|
396
|
+
"required": ["name", "type"],
|
|
397
|
+
"additionalProperties": false,
|
|
398
|
+
"properties": {
|
|
399
|
+
"name": { "type": "string" },
|
|
400
|
+
"type": { "const": "decimal" },
|
|
401
|
+
"label": { "type": "string" },
|
|
402
|
+
"required": { "type": "boolean" },
|
|
403
|
+
"format": {
|
|
404
|
+
"type": "string",
|
|
405
|
+
"description": "Display format",
|
|
406
|
+
"enum": ["currency", "percentage", "plain"]
|
|
407
|
+
},
|
|
408
|
+
"precision": {
|
|
409
|
+
"type": "integer",
|
|
410
|
+
"description": "Total number of digits",
|
|
411
|
+
"minimum": 1,
|
|
412
|
+
"maximum": 65
|
|
413
|
+
},
|
|
414
|
+
"scale": {
|
|
415
|
+
"type": "integer",
|
|
416
|
+
"description": "Number of decimal places",
|
|
417
|
+
"minimum": 0,
|
|
418
|
+
"maximum": 30
|
|
419
|
+
},
|
|
420
|
+
"hint": { "type": "string" },
|
|
421
|
+
"placeholder": {
|
|
422
|
+
"type": "string",
|
|
423
|
+
"description": "Placeholder text displayed in the decimal input"
|
|
424
|
+
},
|
|
425
|
+
"default": { "type": "number" },
|
|
426
|
+
"hidden": {
|
|
427
|
+
"type": "boolean",
|
|
428
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
"selectField": {
|
|
433
|
+
"type": "object",
|
|
434
|
+
"description": "Dropdown select field",
|
|
435
|
+
"required": ["name", "type", "options"],
|
|
436
|
+
"additionalProperties": false,
|
|
437
|
+
"properties": {
|
|
438
|
+
"name": { "type": "string" },
|
|
439
|
+
"type": { "const": "select" },
|
|
440
|
+
"label": { "type": "string" },
|
|
441
|
+
"required": { "type": "boolean" },
|
|
442
|
+
"hint": { "type": "string" },
|
|
443
|
+
"options": {
|
|
444
|
+
"type": "array",
|
|
445
|
+
"description": "Available options for the select",
|
|
446
|
+
"items": {
|
|
447
|
+
"type": "object",
|
|
448
|
+
"required": ["label", "value"],
|
|
449
|
+
"additionalProperties": false,
|
|
450
|
+
"properties": {
|
|
451
|
+
"label": {
|
|
452
|
+
"type": "string",
|
|
453
|
+
"description": "Display label"
|
|
454
|
+
},
|
|
455
|
+
"value": {
|
|
456
|
+
"type": "string",
|
|
457
|
+
"description": "Value stored in database"
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
"minItems": 1
|
|
462
|
+
},
|
|
463
|
+
"default": { "type": "string" },
|
|
464
|
+
"hidden": {
|
|
465
|
+
"type": "boolean",
|
|
466
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
},
|
|
470
|
+
"listField": {
|
|
471
|
+
"type": "object",
|
|
472
|
+
"description": "Repeatable list of items with nested fields",
|
|
473
|
+
"required": ["name", "type"],
|
|
474
|
+
"additionalProperties": false,
|
|
475
|
+
"properties": {
|
|
476
|
+
"name": { "type": "string" },
|
|
477
|
+
"type": { "const": "list" },
|
|
478
|
+
"label": { "type": "string" },
|
|
479
|
+
"required": { "type": "boolean" },
|
|
480
|
+
"maxItems": {
|
|
481
|
+
"type": "integer",
|
|
482
|
+
"description": "Maximum number of items allowed",
|
|
483
|
+
"minimum": 1
|
|
484
|
+
},
|
|
485
|
+
"length": {
|
|
486
|
+
"type": "integer",
|
|
487
|
+
"description": "Maximum length for simple list items"
|
|
488
|
+
},
|
|
489
|
+
"hint": { "type": "string" },
|
|
490
|
+
"hidden": {
|
|
491
|
+
"type": "boolean",
|
|
492
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
493
|
+
},
|
|
494
|
+
"showWhen": { "$ref": "#/$defs/showWhenCondition" },
|
|
495
|
+
"fields": {
|
|
496
|
+
"type": "array",
|
|
497
|
+
"description": "Nested field definitions for complex list items",
|
|
498
|
+
"items": {
|
|
499
|
+
"$ref": "#/$defs/field"
|
|
500
|
+
}
|
|
501
|
+
},
|
|
502
|
+
"items": {
|
|
503
|
+
"description": "Single field definition for simple list items",
|
|
504
|
+
"$ref": "#/$defs/simpleListItem"
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
},
|
|
508
|
+
"simpleListItem": {
|
|
509
|
+
"type": "object",
|
|
510
|
+
"description": "Simple list item definition",
|
|
511
|
+
"required": ["name", "type"],
|
|
512
|
+
"additionalProperties": false,
|
|
513
|
+
"properties": {
|
|
514
|
+
"name": { "type": "string" },
|
|
515
|
+
"type": { "type": "string" },
|
|
516
|
+
"label": { "type": "string" },
|
|
517
|
+
"required": { "type": "boolean" },
|
|
518
|
+
"length": { "type": "integer" }
|
|
519
|
+
}
|
|
520
|
+
},
|
|
521
|
+
"groupField": {
|
|
522
|
+
"type": "object",
|
|
523
|
+
"description": "Group of fields displayed together",
|
|
524
|
+
"required": ["name", "type", "fields"],
|
|
525
|
+
"additionalProperties": false,
|
|
526
|
+
"properties": {
|
|
527
|
+
"name": { "type": "string" },
|
|
528
|
+
"type": { "const": "group" },
|
|
529
|
+
"label": { "type": "string" },
|
|
530
|
+
"columns": {
|
|
531
|
+
"type": "integer",
|
|
532
|
+
"description": "Number of columns for layout",
|
|
533
|
+
"minimum": 1,
|
|
534
|
+
"maximum": 4
|
|
535
|
+
},
|
|
536
|
+
"fields": {
|
|
537
|
+
"type": "array",
|
|
538
|
+
"description": "Nested field definitions",
|
|
539
|
+
"items": {
|
|
540
|
+
"$ref": "#/$defs/field"
|
|
541
|
+
},
|
|
542
|
+
"minItems": 1
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
"tabsField": {
|
|
547
|
+
"type": "object",
|
|
548
|
+
"description": "Tabbed interface for organizing fields",
|
|
549
|
+
"required": ["name", "type", "tabs"],
|
|
550
|
+
"additionalProperties": false,
|
|
551
|
+
"properties": {
|
|
552
|
+
"name": { "type": "string" },
|
|
553
|
+
"type": { "const": "tabs" },
|
|
554
|
+
"tabs": {
|
|
555
|
+
"type": "array",
|
|
556
|
+
"description": "Tab definitions",
|
|
557
|
+
"items": {
|
|
558
|
+
"$ref": "#/$defs/tab"
|
|
559
|
+
},
|
|
560
|
+
"minItems": 1
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
},
|
|
564
|
+
"relationshipField": {
|
|
565
|
+
"type": "object",
|
|
566
|
+
"description": "Relationship field linking to another schema/entity",
|
|
567
|
+
"required": ["name", "type", "relationship"],
|
|
568
|
+
"additionalProperties": false,
|
|
569
|
+
"properties": {
|
|
570
|
+
"name": { "type": "string" },
|
|
571
|
+
"type": { "const": "relationship" },
|
|
572
|
+
"relationship": {
|
|
573
|
+
"type": "string",
|
|
574
|
+
"description": "Name of the related schema/entity (e.g., 'instructors', 'courses')"
|
|
575
|
+
},
|
|
576
|
+
"label": { "type": "string" },
|
|
577
|
+
"required": { "type": "boolean" },
|
|
578
|
+
"hint": { "type": "string" },
|
|
579
|
+
"multiple": {
|
|
580
|
+
"type": "boolean",
|
|
581
|
+
"description": "Whether multiple items can be selected",
|
|
582
|
+
"default": false
|
|
583
|
+
},
|
|
584
|
+
"hidden": {
|
|
585
|
+
"type": "boolean",
|
|
586
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
587
|
+
},
|
|
588
|
+
"showWhen": { "$ref": "#/$defs/showWhenCondition" }
|
|
589
|
+
}
|
|
590
|
+
},
|
|
591
|
+
"separatorField": {
|
|
592
|
+
"type": "object",
|
|
593
|
+
"description": "Visual separator between form fields",
|
|
594
|
+
"required": ["type"],
|
|
595
|
+
"additionalProperties": false,
|
|
596
|
+
"properties": {
|
|
597
|
+
"name": { "type": "string" },
|
|
598
|
+
"type": { "const": "separator" },
|
|
599
|
+
"label": {
|
|
600
|
+
"type": "string",
|
|
601
|
+
"description": "Optional label to display with the separator"
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
},
|
|
605
|
+
"videoField": {
|
|
606
|
+
"type": "object",
|
|
607
|
+
"description": "Video upload field",
|
|
608
|
+
"required": ["name", "type"],
|
|
609
|
+
"additionalProperties": false,
|
|
610
|
+
"properties": {
|
|
611
|
+
"name": { "type": "string" },
|
|
612
|
+
"type": { "const": "video" },
|
|
613
|
+
"label": { "type": "string" },
|
|
614
|
+
"required": { "type": "boolean" },
|
|
615
|
+
"hint": { "type": "string" },
|
|
616
|
+
"maxSizeInMB": {
|
|
617
|
+
"type": "integer",
|
|
618
|
+
"description": "Maximum file size in megabytes",
|
|
619
|
+
"default": 100
|
|
620
|
+
},
|
|
621
|
+
"hidden": {
|
|
622
|
+
"type": "boolean",
|
|
623
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
},
|
|
627
|
+
"mediaField": {
|
|
628
|
+
"type": "object",
|
|
629
|
+
"description": "Media upload field supporting both images and videos",
|
|
630
|
+
"required": ["name", "type"],
|
|
631
|
+
"additionalProperties": false,
|
|
632
|
+
"properties": {
|
|
633
|
+
"name": { "type": "string" },
|
|
634
|
+
"type": { "const": "media" },
|
|
635
|
+
"label": { "type": "string" },
|
|
636
|
+
"required": { "type": "boolean" },
|
|
637
|
+
"hint": { "type": "string" },
|
|
638
|
+
"maxSizeInMB": {
|
|
639
|
+
"type": "integer",
|
|
640
|
+
"description": "Maximum file size in megabytes",
|
|
641
|
+
"default": 100
|
|
642
|
+
},
|
|
643
|
+
"hidden": {
|
|
644
|
+
"type": "boolean",
|
|
645
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
},
|
|
649
|
+
"githubRepoField": {
|
|
650
|
+
"type": "object",
|
|
651
|
+
"description": "GitHub repository selection combobox field",
|
|
652
|
+
"required": ["name", "type"],
|
|
653
|
+
"additionalProperties": false,
|
|
654
|
+
"properties": {
|
|
655
|
+
"name": { "type": "string" },
|
|
656
|
+
"type": { "const": "github-repo" },
|
|
657
|
+
"label": { "type": "string" },
|
|
658
|
+
"required": { "type": "boolean" },
|
|
659
|
+
"hint": { "type": "string" },
|
|
660
|
+
"showWhen": { "$ref": "#/$defs/showWhenCondition" }
|
|
661
|
+
}
|
|
662
|
+
},
|
|
663
|
+
"githubBranchField": {
|
|
664
|
+
"type": "object",
|
|
665
|
+
"description": "GitHub branch selection combobox field (depends on a repo field)",
|
|
666
|
+
"required": ["name", "type", "dependsOn"],
|
|
667
|
+
"additionalProperties": false,
|
|
668
|
+
"properties": {
|
|
669
|
+
"name": { "type": "string" },
|
|
670
|
+
"type": { "const": "github-branch" },
|
|
671
|
+
"label": { "type": "string" },
|
|
672
|
+
"required": { "type": "boolean" },
|
|
673
|
+
"hint": { "type": "string" },
|
|
674
|
+
"showWhen": { "$ref": "#/$defs/showWhenCondition" },
|
|
675
|
+
"dependsOn": { "$ref": "#/$defs/dependsOnCondition" }
|
|
676
|
+
}
|
|
677
|
+
},
|
|
678
|
+
"githubDirectoryField": {
|
|
679
|
+
"type": "object",
|
|
680
|
+
"description": "GitHub directory selection combobox field (depends on repo and branch fields)",
|
|
681
|
+
"required": ["name", "type", "dependsOn"],
|
|
682
|
+
"additionalProperties": false,
|
|
683
|
+
"properties": {
|
|
684
|
+
"name": { "type": "string" },
|
|
685
|
+
"type": { "const": "github-directory" },
|
|
686
|
+
"label": { "type": "string" },
|
|
687
|
+
"required": { "type": "boolean" },
|
|
688
|
+
"hint": { "type": "string" },
|
|
689
|
+
"showWhen": { "$ref": "#/$defs/showWhenCondition" },
|
|
690
|
+
"dependsOn": { "$ref": "#/$defs/dependsOnCondition" }
|
|
691
|
+
}
|
|
692
|
+
},
|
|
693
|
+
"githubChaptersField": {
|
|
694
|
+
"type": "object",
|
|
695
|
+
"description": "GitHub chapters loader field - loads markdown files from a directory as chapters",
|
|
696
|
+
"required": ["name", "type", "dependsOn", "fields"],
|
|
697
|
+
"additionalProperties": false,
|
|
698
|
+
"properties": {
|
|
699
|
+
"name": { "type": "string" },
|
|
700
|
+
"type": { "const": "github-chapters" },
|
|
701
|
+
"label": { "type": "string" },
|
|
702
|
+
"required": { "type": "boolean" },
|
|
703
|
+
"hint": { "type": "string" },
|
|
704
|
+
"showWhen": { "$ref": "#/$defs/showWhenCondition" },
|
|
705
|
+
"dependsOn": { "$ref": "#/$defs/dependsOnCondition" },
|
|
706
|
+
"fields": {
|
|
707
|
+
"type": "array",
|
|
708
|
+
"items": { "$ref": "#/$defs/field" },
|
|
709
|
+
"description": "Fields for each chapter (title, slug, description)"
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
},
|
|
713
|
+
"curriculumField": {
|
|
714
|
+
"type": "object",
|
|
715
|
+
"description": "Curriculum editor field with sequential or weekly mode support",
|
|
716
|
+
"required": ["name", "type"],
|
|
717
|
+
"additionalProperties": false,
|
|
718
|
+
"properties": {
|
|
719
|
+
"name": { "type": "string" },
|
|
720
|
+
"type": { "const": "curriculum" },
|
|
721
|
+
"label": { "type": "string" },
|
|
722
|
+
"required": { "type": "boolean" },
|
|
723
|
+
"hint": { "type": "string" },
|
|
724
|
+
"hidden": {
|
|
725
|
+
"type": "boolean",
|
|
726
|
+
"description": "Whether this field is hidden from the form UI but still exists in the database"
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
},
|
|
730
|
+
"tab": {
|
|
731
|
+
"type": "object",
|
|
732
|
+
"description": "A single tab containing fields",
|
|
733
|
+
"required": ["name", "label", "fields"],
|
|
734
|
+
"additionalProperties": false,
|
|
735
|
+
"properties": {
|
|
736
|
+
"name": {
|
|
737
|
+
"type": "string",
|
|
738
|
+
"description": "Tab identifier"
|
|
739
|
+
},
|
|
740
|
+
"label": {
|
|
741
|
+
"type": "string",
|
|
742
|
+
"description": "Tab display label"
|
|
743
|
+
},
|
|
744
|
+
"fields": {
|
|
745
|
+
"type": "array",
|
|
746
|
+
"description": "Fields within this tab",
|
|
747
|
+
"items": {
|
|
748
|
+
"$ref": "#/$defs/field"
|
|
749
|
+
},
|
|
750
|
+
"minItems": 1
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
},
|
|
754
|
+
"column": {
|
|
755
|
+
"type": "object",
|
|
756
|
+
"description": "Table column definition for list views",
|
|
757
|
+
"required": ["accessorKey", "header"],
|
|
758
|
+
"additionalProperties": false,
|
|
759
|
+
"properties": {
|
|
760
|
+
"accessorKey": {
|
|
761
|
+
"type": "string",
|
|
762
|
+
"description": "Field name to access data from"
|
|
763
|
+
},
|
|
764
|
+
"header": {
|
|
765
|
+
"type": "string",
|
|
766
|
+
"description": "Column header text"
|
|
767
|
+
},
|
|
768
|
+
"type": {
|
|
769
|
+
"type": "string",
|
|
770
|
+
"description": "Column display type",
|
|
771
|
+
"enum": ["image", "text", "badge", "date", "number", "link"]
|
|
772
|
+
},
|
|
773
|
+
"sortable": {
|
|
774
|
+
"type": "boolean",
|
|
775
|
+
"description": "Whether the column is sortable",
|
|
776
|
+
"default": false
|
|
777
|
+
},
|
|
778
|
+
"format": {
|
|
779
|
+
"type": "string",
|
|
780
|
+
"description": "Display format (e.g., 'currency' for numbers)",
|
|
781
|
+
"enum": ["currency", "percentage"]
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
},
|
|
785
|
+
"actions": {
|
|
786
|
+
"type": "object",
|
|
787
|
+
"description": "CRUD action configuration",
|
|
788
|
+
"additionalProperties": false,
|
|
789
|
+
"properties": {
|
|
790
|
+
"draft": {
|
|
791
|
+
"type": "boolean",
|
|
792
|
+
"description": "Enable draft/publish workflow",
|
|
793
|
+
"default": false
|
|
794
|
+
},
|
|
795
|
+
"create": {
|
|
796
|
+
"type": "boolean",
|
|
797
|
+
"description": "Enable create action",
|
|
798
|
+
"default": true
|
|
799
|
+
},
|
|
800
|
+
"edit": {
|
|
801
|
+
"type": "boolean",
|
|
802
|
+
"description": "Enable edit action",
|
|
803
|
+
"default": true
|
|
804
|
+
},
|
|
805
|
+
"delete": {
|
|
806
|
+
"type": "boolean",
|
|
807
|
+
"description": "Enable delete action",
|
|
808
|
+
"default": true
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
},
|
|
812
|
+
"search": {
|
|
813
|
+
"type": "object",
|
|
814
|
+
"description": "Backend search configuration for admin tables",
|
|
815
|
+
"additionalProperties": false,
|
|
816
|
+
"required": ["fields"],
|
|
817
|
+
"properties": {
|
|
818
|
+
"fields": {
|
|
819
|
+
"type": "array",
|
|
820
|
+
"description": "Array of field names to search across (should be text-type columns like string, text, varchar)",
|
|
821
|
+
"items": {
|
|
822
|
+
"type": "string",
|
|
823
|
+
"description": "Field name to include in search"
|
|
824
|
+
},
|
|
825
|
+
"minItems": 1
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
},
|
|
829
|
+
"filters": {
|
|
830
|
+
"type": "array",
|
|
831
|
+
"description": "Filter configuration for admin tables",
|
|
832
|
+
"items": {
|
|
833
|
+
"$ref": "#/$defs/filter"
|
|
834
|
+
}
|
|
835
|
+
},
|
|
836
|
+
"filter": {
|
|
837
|
+
"type": "object",
|
|
838
|
+
"description": "Filter definition for admin tables",
|
|
839
|
+
"required": ["field", "label"],
|
|
840
|
+
"additionalProperties": false,
|
|
841
|
+
"properties": {
|
|
842
|
+
"field": {
|
|
843
|
+
"type": "string",
|
|
844
|
+
"description": "Field name to filter by"
|
|
845
|
+
},
|
|
846
|
+
"label": {
|
|
847
|
+
"type": "string",
|
|
848
|
+
"description": "Label for the filter dropdown"
|
|
849
|
+
},
|
|
850
|
+
"type": {
|
|
851
|
+
"type": "string",
|
|
852
|
+
"description": "Filter type",
|
|
853
|
+
"enum": ["select"],
|
|
854
|
+
"default": "select"
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
},
|
|
858
|
+
"repoConfig": {
|
|
859
|
+
"type": "object",
|
|
860
|
+
"description": "GitHub repository configuration for syncing content",
|
|
861
|
+
"required": ["path", "branch"],
|
|
862
|
+
"additionalProperties": false,
|
|
863
|
+
"properties": {
|
|
864
|
+
"path": {
|
|
865
|
+
"type": "string",
|
|
866
|
+
"description": "GitHub repository path (e.g., 'owner/repo')"
|
|
867
|
+
},
|
|
868
|
+
"branch": {
|
|
869
|
+
"type": "string",
|
|
870
|
+
"description": "Git branch to sync from"
|
|
871
|
+
},
|
|
872
|
+
"basePath": {
|
|
873
|
+
"type": "string",
|
|
874
|
+
"description": "Base path within the repository to sync files from"
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
},
|
|
878
|
+
"autoCategorize": {
|
|
879
|
+
"type": "object",
|
|
880
|
+
"description": "Auto-categorization configuration for GitHub-synced schemas",
|
|
881
|
+
"additionalProperties": false,
|
|
882
|
+
"properties": {
|
|
883
|
+
"enabled": {
|
|
884
|
+
"type": "boolean",
|
|
885
|
+
"description": "Enable automatic categorization during GitHub sync",
|
|
886
|
+
"default": true
|
|
887
|
+
},
|
|
888
|
+
"useRepoName": {
|
|
889
|
+
"type": "boolean",
|
|
890
|
+
"description": "Automatically create/assign category based on repository name",
|
|
891
|
+
"default": true
|
|
892
|
+
},
|
|
893
|
+
"keywords": {
|
|
894
|
+
"type": "array",
|
|
895
|
+
"description": "Keyword-based categorization rules",
|
|
896
|
+
"items": {
|
|
897
|
+
"$ref": "#/$defs/categoryKeyword"
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
},
|
|
902
|
+
"categoryKeyword": {
|
|
903
|
+
"type": "object",
|
|
904
|
+
"description": "Keyword rule for auto-categorization",
|
|
905
|
+
"required": ["category", "patterns"],
|
|
906
|
+
"additionalProperties": false,
|
|
907
|
+
"properties": {
|
|
908
|
+
"category": {
|
|
909
|
+
"type": "string",
|
|
910
|
+
"description": "Category name to assign when patterns match"
|
|
911
|
+
},
|
|
912
|
+
"patterns": {
|
|
913
|
+
"type": "array",
|
|
914
|
+
"description": "Array of keywords/patterns to match against title and content",
|
|
915
|
+
"items": {
|
|
916
|
+
"type": "string"
|
|
917
|
+
},
|
|
918
|
+
"minItems": 1
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
},
|
|
922
|
+
"autoSlugify": {
|
|
923
|
+
"type": "object",
|
|
924
|
+
"description": "Auto-slugification configuration for generating URL-friendly slugs from fields",
|
|
925
|
+
"additionalProperties": false,
|
|
926
|
+
"properties": {
|
|
927
|
+
"enabled": {
|
|
928
|
+
"type": "boolean",
|
|
929
|
+
"description": "Enable automatic slug generation",
|
|
930
|
+
"default": true
|
|
931
|
+
},
|
|
932
|
+
"sourceField": {
|
|
933
|
+
"type": "string",
|
|
934
|
+
"description": "Field to use as source for slug generation (e.g., 'name', 'title')"
|
|
935
|
+
},
|
|
936
|
+
"targetField": {
|
|
937
|
+
"type": "string",
|
|
938
|
+
"description": "Field to store the generated slug (typically 'slug')"
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
},
|
|
942
|
+
"githubSyncPage": {
|
|
943
|
+
"type": "object",
|
|
944
|
+
"description": "GitHub sync page configuration for displaying sync status and controls",
|
|
945
|
+
"additionalProperties": false,
|
|
946
|
+
"properties": {
|
|
947
|
+
"enabled": {
|
|
948
|
+
"type": "boolean",
|
|
949
|
+
"description": "Enable GitHub sync page",
|
|
950
|
+
"default": false
|
|
951
|
+
},
|
|
952
|
+
"route": {
|
|
953
|
+
"type": "string",
|
|
954
|
+
"description": "Route path for the sync page (e.g., 'github-sync')"
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
}
|