@proteos/sdk 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +40 -0
- package/dist/chunk-7RGN4E22.cjs +1185 -0
- package/dist/chunk-7RGN4E22.cjs.map +1 -0
- package/dist/chunk-XJP5WCRZ.js +1125 -0
- package/dist/chunk-XJP5WCRZ.js.map +1 -0
- package/dist/index.cjs +2384 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +5225 -0
- package/dist/index.d.ts +5225 -0
- package/dist/index.js +2146 -0
- package/dist/index.js.map +1 -0
- package/dist/meta/index.cjs +204 -0
- package/dist/meta/index.cjs.map +1 -0
- package/dist/meta/index.d.cts +2 -0
- package/dist/meta/index.d.ts +2 -0
- package/dist/meta/index.js +3 -0
- package/dist/meta/index.js.map +1 -0
- package/dist/types-BNsjfU8N.d.cts +3299 -0
- package/dist/types-BNsjfU8N.d.ts +3299 -0
- package/package.json +86 -0
- package/src/agent/agents.ts +53 -0
- package/src/agent/index.ts +134 -0
- package/src/agent/mcp-servers.ts +102 -0
- package/src/agent/prompts.ts +80 -0
- package/src/agent/session-types.ts +397 -0
- package/src/agent/sessions.ts +197 -0
- package/src/agent/skills.ts +89 -0
- package/src/agent/tools.ts +53 -0
- package/src/agent/types.ts +362 -0
- package/src/auth/index.ts +111 -0
- package/src/auth/me.ts +46 -0
- package/src/auth/organizations.ts +128 -0
- package/src/auth/platform-entities.ts +78 -0
- package/src/auth/roles.ts +213 -0
- package/src/auth/types.ts +294 -0
- package/src/auth/users.ts +226 -0
- package/src/client.ts +441 -0
- package/src/connector/index.ts +120 -0
- package/src/connector/types.ts +150 -0
- package/src/conversation/index.ts +297 -0
- package/src/conversation/types.ts +590 -0
- package/src/conversation/voice.ts +123 -0
- package/src/data/index.ts +53 -0
- package/src/data/queries.ts +66 -0
- package/src/data/records.ts +122 -0
- package/src/data/types.ts +89 -0
- package/src/errors.ts +148 -0
- package/src/events/index.ts +172 -0
- package/src/events/types.ts +77 -0
- package/src/functions/actions.ts +95 -0
- package/src/functions/index.ts +32 -0
- package/src/functions/types.ts +71 -0
- package/src/http/index.ts +2 -0
- package/src/http/query-params.ts +106 -0
- package/src/index.ts +598 -0
- package/src/iterator.ts +183 -0
- package/src/knowledge/graph.ts +35 -0
- package/src/knowledge/index.ts +104 -0
- package/src/knowledge/labels.ts +70 -0
- package/src/knowledge/links.ts +65 -0
- package/src/knowledge/nodes.ts +198 -0
- package/src/knowledge/record-links.ts +66 -0
- package/src/knowledge/types.ts +569 -0
- package/src/meta/apps.ts +107 -0
- package/src/meta/components.ts +124 -0
- package/src/meta/currency/index.ts +202 -0
- package/src/meta/entities.ts +193 -0
- package/src/meta/filters.ts +76 -0
- package/src/meta/index.ts +227 -0
- package/src/meta/layout/common-props.ts +93 -0
- package/src/meta/layout/control-registry.json +70 -0
- package/src/meta/layout/control-registry.ts +92 -0
- package/src/meta/layout/elements.ts +203 -0
- package/src/meta/layout/index.ts +41 -0
- package/src/meta/layout/page-layout.ts +35 -0
- package/src/meta/layout/size-value.ts +27 -0
- package/src/meta/list-views.ts +109 -0
- package/src/meta/lists.ts +104 -0
- package/src/meta/menu-configurations.ts +128 -0
- package/src/meta/modules.ts +159 -0
- package/src/meta/pages.ts +106 -0
- package/src/meta/types.ts +1115 -0
- package/src/meta/variables.ts +98 -0
- package/src/storage/files.ts +183 -0
- package/src/storage/index.ts +33 -0
- package/src/storage/types.ts +70 -0
- package/src/types/common.ts +143 -0
- package/src/types/index.ts +28 -0
- package/src/types/options.ts +95 -0
- package/src/workflow/executions.ts +99 -0
- package/src/workflow/index.ts +109 -0
- package/src/workflow/node-types.ts +50 -0
- package/src/workflow/types.ts +658 -0
- package/src/workflow/workflows.ts +152 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import type { ProteosClient } from '../client.js'
|
|
2
|
+
import { type AppService, AppServiceImpl } from './apps.js'
|
|
3
|
+
import { type ComponentService, ComponentServiceImpl } from './components.js'
|
|
4
|
+
import { type EntityService, EntityServiceImpl } from './entities.js'
|
|
5
|
+
import { type ListViewService, ListViewServiceImpl } from './list-views.js'
|
|
6
|
+
import { type ListService, ListServiceImpl } from './lists.js'
|
|
7
|
+
import {
|
|
8
|
+
type MenuConfigurationService,
|
|
9
|
+
MenuConfigurationServiceImpl,
|
|
10
|
+
} from './menu-configurations.js'
|
|
11
|
+
import { type ModuleService, ModuleServiceImpl } from './modules.js'
|
|
12
|
+
import { type PageService, PageServiceImpl } from './pages.js'
|
|
13
|
+
import { type VariableService, VariableServiceImpl } from './variables.js'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Client for the Proteos Metadata Service API.
|
|
17
|
+
* Provides access to all metadata management services.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { ProteosClient, MetaClient } from 'proteos-sdk';
|
|
22
|
+
*
|
|
23
|
+
* const client = new ProteosClient({
|
|
24
|
+
* baseUrl: 'https://api.proteos.ai',
|
|
25
|
+
* token: 'your-api-token',
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* const meta = new MetaClient(client);
|
|
29
|
+
*
|
|
30
|
+
* // Use services
|
|
31
|
+
* const entities = await meta.entities.list().all();
|
|
32
|
+
* const module = await meta.modules.get('my-module');
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export class MetaClient {
|
|
36
|
+
/**
|
|
37
|
+
* Service for managing entity definitions.
|
|
38
|
+
*/
|
|
39
|
+
readonly entities: EntityService
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Service for managing WebAssembly modules.
|
|
43
|
+
*/
|
|
44
|
+
readonly modules: ModuleService
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Service for managing configuration and secret variables.
|
|
48
|
+
*/
|
|
49
|
+
readonly variables: VariableService
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Service for managing UI component definitions.
|
|
53
|
+
*/
|
|
54
|
+
readonly components: ComponentService
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Service for managing list configurations.
|
|
58
|
+
*/
|
|
59
|
+
readonly lists: ListService
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Service for managing list view configurations.
|
|
63
|
+
*/
|
|
64
|
+
readonly listViews: ListViewService
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Service for managing page configurations.
|
|
68
|
+
*/
|
|
69
|
+
readonly pages: PageService
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Service for managing menu configurations.
|
|
73
|
+
*/
|
|
74
|
+
readonly menuConfigurations: MenuConfigurationService
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Service for managing apps.
|
|
78
|
+
*/
|
|
79
|
+
readonly apps: AppService
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Creates a new MetaClient instance.
|
|
83
|
+
*
|
|
84
|
+
* @param client - The base ProteosClient to use for API requests
|
|
85
|
+
*/
|
|
86
|
+
constructor(client: ProteosClient) {
|
|
87
|
+
this.entities = new EntityServiceImpl(client)
|
|
88
|
+
this.modules = new ModuleServiceImpl(client)
|
|
89
|
+
this.variables = new VariableServiceImpl(client)
|
|
90
|
+
this.components = new ComponentServiceImpl(client)
|
|
91
|
+
this.lists = new ListServiceImpl(client)
|
|
92
|
+
this.listViews = new ListViewServiceImpl(client)
|
|
93
|
+
this.pages = new PageServiceImpl(client)
|
|
94
|
+
this.menuConfigurations = new MenuConfigurationServiceImpl(client)
|
|
95
|
+
this.apps = new AppServiceImpl(client)
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export type { AppService } from './apps.js'
|
|
100
|
+
export type { ComponentService } from './components.js'
|
|
101
|
+
export * from './currency/index.js'
|
|
102
|
+
// Re-export service interfaces
|
|
103
|
+
export type { EntityService } from './entities.js'
|
|
104
|
+
// Re-export the layout module (PageLayout types + Zod schemas + control registry)
|
|
105
|
+
export * from './layout/index.js'
|
|
106
|
+
export type { ListViewService } from './list-views.js'
|
|
107
|
+
export type { ListService } from './lists.js'
|
|
108
|
+
export type { MenuConfigurationService } from './menu-configurations.js'
|
|
109
|
+
export type { ModuleService } from './modules.js'
|
|
110
|
+
export type { PageService } from './pages.js'
|
|
111
|
+
// Re-export types
|
|
112
|
+
export type {
|
|
113
|
+
// App types
|
|
114
|
+
App,
|
|
115
|
+
ArrayAttributeMeta,
|
|
116
|
+
Attribute,
|
|
117
|
+
AttributeMeta,
|
|
118
|
+
AttributeType,
|
|
119
|
+
Column,
|
|
120
|
+
ComparisonOperator,
|
|
121
|
+
// Component types
|
|
122
|
+
Component,
|
|
123
|
+
CreateAppRequest,
|
|
124
|
+
CreateComponentRequest,
|
|
125
|
+
CreateEntityRequest,
|
|
126
|
+
CreateListRequest,
|
|
127
|
+
CreateListViewRequest,
|
|
128
|
+
CreateMenuConfigurationRequest,
|
|
129
|
+
CreatePageRequest,
|
|
130
|
+
CreateVariableRequest,
|
|
131
|
+
// Currency attribute meta + value
|
|
132
|
+
CurrencyAttributeMeta,
|
|
133
|
+
CurrencyValue,
|
|
134
|
+
DatetimeAttributeMeta,
|
|
135
|
+
DatetimeFormat,
|
|
136
|
+
DeployModuleRequest,
|
|
137
|
+
// Entity types
|
|
138
|
+
Entity,
|
|
139
|
+
EntityWithSchema,
|
|
140
|
+
EnumAttributeMeta,
|
|
141
|
+
EnumValue,
|
|
142
|
+
// File attribute meta
|
|
143
|
+
FileAttributeMeta,
|
|
144
|
+
FilterElement,
|
|
145
|
+
FilterGroup,
|
|
146
|
+
// List types
|
|
147
|
+
List,
|
|
148
|
+
ListAppsOptions,
|
|
149
|
+
ListComponentsOptions,
|
|
150
|
+
ListEntitiesOptions,
|
|
151
|
+
ListListsOptions,
|
|
152
|
+
ListListViewsOptions,
|
|
153
|
+
ListMenuConfigurationsOptions,
|
|
154
|
+
ListModulesOptions,
|
|
155
|
+
ListPagesOptions,
|
|
156
|
+
ListVariablesOptions,
|
|
157
|
+
// ListView types
|
|
158
|
+
ListView,
|
|
159
|
+
LogicalOperator,
|
|
160
|
+
// MenuConfiguration types
|
|
161
|
+
MenuConfiguration,
|
|
162
|
+
MenuItem,
|
|
163
|
+
// Shared types
|
|
164
|
+
MetaListOptions,
|
|
165
|
+
// Module types
|
|
166
|
+
Module,
|
|
167
|
+
ModuleStatus,
|
|
168
|
+
NumberAttributeMeta,
|
|
169
|
+
ObjectAttributeMeta,
|
|
170
|
+
OnDeleteAction,
|
|
171
|
+
// Page types
|
|
172
|
+
Page,
|
|
173
|
+
PageAction,
|
|
174
|
+
// Relation attribute meta
|
|
175
|
+
RelationAttributeMeta,
|
|
176
|
+
SortConfig,
|
|
177
|
+
SortDirection,
|
|
178
|
+
StringAttributeMeta,
|
|
179
|
+
StringFormat,
|
|
180
|
+
UpdateAppRequest,
|
|
181
|
+
UpdateComponentRequest,
|
|
182
|
+
UpdateEntityRequest,
|
|
183
|
+
UpdateListRequest,
|
|
184
|
+
UpdateListViewRequest,
|
|
185
|
+
UpdateMenuConfigurationRequest,
|
|
186
|
+
UpdatePageRequest,
|
|
187
|
+
UpdateVariableRequest,
|
|
188
|
+
// User attribute meta
|
|
189
|
+
UserAttributeMeta,
|
|
190
|
+
// Variable types
|
|
191
|
+
Variable,
|
|
192
|
+
} from './types.js'
|
|
193
|
+
// Re-export value-level constants
|
|
194
|
+
// Re-export Zod schemas
|
|
195
|
+
export {
|
|
196
|
+
AppSchema,
|
|
197
|
+
AttributeSchema,
|
|
198
|
+
ColumnSchema,
|
|
199
|
+
ComponentSchema,
|
|
200
|
+
CurrencyAttributeMetaSchema,
|
|
201
|
+
EntitySchema,
|
|
202
|
+
EntityWithSchemaSchema,
|
|
203
|
+
FileAttributeMetaSchema,
|
|
204
|
+
FilterElementSchema,
|
|
205
|
+
FilterGroupSchema,
|
|
206
|
+
isPlatformAttributeName,
|
|
207
|
+
ListSchema,
|
|
208
|
+
ListViewSchema,
|
|
209
|
+
MenuConfigurationSchema,
|
|
210
|
+
MenuItemSchema,
|
|
211
|
+
MenuItemType,
|
|
212
|
+
ModuleSchema,
|
|
213
|
+
OnDeleteActionSchema,
|
|
214
|
+
PageActionSchema,
|
|
215
|
+
PageSchema,
|
|
216
|
+
PLATFORM_ATTRIBUTE_NAMES,
|
|
217
|
+
parseCurrencyMeta,
|
|
218
|
+
parseFileMeta,
|
|
219
|
+
parseRelationMeta,
|
|
220
|
+
parseUserMeta,
|
|
221
|
+
platformAttributes,
|
|
222
|
+
RelationAttributeMetaSchema,
|
|
223
|
+
SortConfigSchema,
|
|
224
|
+
UserAttributeMetaSchema,
|
|
225
|
+
VariableSchema,
|
|
226
|
+
} from './types.js'
|
|
227
|
+
export type { VariableService } from './variables.js'
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import { type FilterGroup, FilterGroupSchema } from '../filters.js'
|
|
3
|
+
import { type SizeValue, SizeValueSchema } from './size-value.js'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Cross-axis alignment values. On Row / Column the same string also drives
|
|
7
|
+
* arrangement of children (cross-axis); on a leaf element it acts as
|
|
8
|
+
* align-self.
|
|
9
|
+
*/
|
|
10
|
+
export type LayoutAlign = 'start' | 'center' | 'end' | 'stretch'
|
|
11
|
+
|
|
12
|
+
export type LayoutJustify = 'start' | 'center' | 'end' | 'between' | 'around'
|
|
13
|
+
|
|
14
|
+
export type LayoutGap = 'xs' | 'sm' | 'md' | 'lg'
|
|
15
|
+
|
|
16
|
+
const AlignSchema = z.enum(['start', 'center', 'end', 'stretch'])
|
|
17
|
+
const JustifySchema = z.enum(['start', 'center', 'end', 'between', 'around'])
|
|
18
|
+
const GapSchema = z.enum(['xs', 'sm', 'md', 'lg'])
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Partial sizing knobs reused by ResponsiveSizing.
|
|
22
|
+
*/
|
|
23
|
+
export interface SizingProps {
|
|
24
|
+
width?: SizeValue
|
|
25
|
+
height?: SizeValue
|
|
26
|
+
grow?: number
|
|
27
|
+
shrink?: number
|
|
28
|
+
align?: LayoutAlign
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const SizingPropsSchema = z.object({
|
|
32
|
+
width: SizeValueSchema.optional(),
|
|
33
|
+
height: SizeValueSchema.optional(),
|
|
34
|
+
grow: z.number().optional(),
|
|
35
|
+
shrink: z.number().optional(),
|
|
36
|
+
align: AlignSchema.optional(),
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
export interface ResponsiveSizing {
|
|
40
|
+
sm?: SizingProps
|
|
41
|
+
md?: SizingProps
|
|
42
|
+
lg?: SizingProps
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const ResponsiveSizingSchema = z.object({
|
|
46
|
+
sm: SizingPropsSchema.optional(),
|
|
47
|
+
md: SizingPropsSchema.optional(),
|
|
48
|
+
lg: SizingPropsSchema.optional(),
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Common properties present on every LayoutElement.
|
|
53
|
+
*
|
|
54
|
+
* `visible_when` and `read_only_when` reuse the `FilterGroup` predicate model
|
|
55
|
+
* already used by lists and the data-service URL query convention — same
|
|
56
|
+
* operators, same and/or composition, same `value: string` (pipe-joined for
|
|
57
|
+
* `in` / `not_in`).
|
|
58
|
+
*
|
|
59
|
+
* `align` here is align-self (override of the parent's cross-axis arrangement
|
|
60
|
+
* for this child). On Row / Column it is shadowed by an outer `align` whose
|
|
61
|
+
* semantic is the cross-axis arrangement applied to children.
|
|
62
|
+
*/
|
|
63
|
+
export interface CommonProps {
|
|
64
|
+
id?: string
|
|
65
|
+
visible_when?: FilterGroup
|
|
66
|
+
read_only_when?: FilterGroup
|
|
67
|
+
width?: SizeValue
|
|
68
|
+
height?: SizeValue
|
|
69
|
+
grow?: number
|
|
70
|
+
shrink?: number
|
|
71
|
+
align?: LayoutAlign
|
|
72
|
+
responsive?: ResponsiveSizing
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The Zod shape for CommonProps. Exported so individual element schemas can
|
|
77
|
+
* spread it via `.extend(commonPropsShape)`.
|
|
78
|
+
*/
|
|
79
|
+
export const commonPropsShape = {
|
|
80
|
+
id: z.string().optional(),
|
|
81
|
+
visible_when: FilterGroupSchema.optional(),
|
|
82
|
+
read_only_when: FilterGroupSchema.optional(),
|
|
83
|
+
width: SizeValueSchema.optional(),
|
|
84
|
+
height: SizeValueSchema.optional(),
|
|
85
|
+
grow: z.number().optional(),
|
|
86
|
+
shrink: z.number().optional(),
|
|
87
|
+
align: AlignSchema.optional(),
|
|
88
|
+
responsive: ResponsiveSizingSchema.optional(),
|
|
89
|
+
} as const
|
|
90
|
+
|
|
91
|
+
export const layoutAlignShape = AlignSchema
|
|
92
|
+
export const layoutJustifyShape = JustifySchema
|
|
93
|
+
export const layoutGapShape = GapSchema
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "SOURCE OF TRUTH for the page-layout control registry. Each entry under `controls` declares the primary control slug and the full compatible list for one (type[+format|+items.type]) combination. Renderer dispatches off `primary`; inspector picker dispatches off `compatible`. Edit this file then run `go run ./scripts/codegen/page-layout-registry` from the repo root to regenerate packages/go/model/page_layout_registry_gen.go.",
|
|
3
|
+
"_attributeTypes": "Top-level keys MUST match the Go canonical AttributeType union in packages/go/model/meta/attribute.go (string · number · integer · boolean · array · object · datetime · enum · relation · user · currency · knowledge-text · file). `byFormat` keys for `string` MUST match StringFormat (email · uri · uuid · hostname · ipv4 · ipv6). `byFormat` keys for `datetime` MUST match DatetimeFormat (date-time · date · time · duration). `byItemsType` for `array` keys on the item Attribute's type. A null `primary` with empty `compatible` means \"render-only fallback\" — see plan §3.2.5.",
|
|
4
|
+
"_slugRoster": "v1 ships only lib-backed slugs. Slugs without a backing @proteos/ui component (markdown · json-editor · slider · stepper · percent · user-card) are intentionally omitted; they return when the matching lib primitive ships. See plan §3.2.4 / §7.3. The `user-picker` slug is backed by the web client's UserCombobox (account/user-service people picker). The `currency` slug is backed by the web client's currency control (CurrencyInput: decimal amount + ISO-4217 picker).",
|
|
5
|
+
"builtInControls": [
|
|
6
|
+
"text",
|
|
7
|
+
"textarea",
|
|
8
|
+
"email",
|
|
9
|
+
"url",
|
|
10
|
+
"password",
|
|
11
|
+
"number",
|
|
12
|
+
"switch",
|
|
13
|
+
"checkbox",
|
|
14
|
+
"select",
|
|
15
|
+
"radio-group",
|
|
16
|
+
"chip-group",
|
|
17
|
+
"multi-select",
|
|
18
|
+
"date-picker",
|
|
19
|
+
"datetime-picker",
|
|
20
|
+
"time-picker",
|
|
21
|
+
"tag-input",
|
|
22
|
+
"entity-picker",
|
|
23
|
+
"user-picker",
|
|
24
|
+
"currency",
|
|
25
|
+
"knowledge-text",
|
|
26
|
+
"file"
|
|
27
|
+
],
|
|
28
|
+
"controls": {
|
|
29
|
+
"string": {
|
|
30
|
+
"primary": "text",
|
|
31
|
+
"compatible": ["text", "textarea", "password"],
|
|
32
|
+
"byFormat": {
|
|
33
|
+
"email": { "primary": "email", "compatible": ["email", "text"] },
|
|
34
|
+
"uri": { "primary": "url", "compatible": ["url", "text"] },
|
|
35
|
+
"uuid": { "primary": "text", "compatible": ["text"] },
|
|
36
|
+
"hostname": { "primary": "text", "compatible": ["text"] },
|
|
37
|
+
"ipv4": { "primary": "text", "compatible": ["text"] },
|
|
38
|
+
"ipv6": { "primary": "text", "compatible": ["text"] }
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"number": { "primary": "number", "compatible": ["number"] },
|
|
42
|
+
"integer": { "primary": "number", "compatible": ["number"] },
|
|
43
|
+
"boolean": { "primary": "switch", "compatible": ["switch", "checkbox"] },
|
|
44
|
+
"enum": { "primary": "select", "compatible": ["select", "radio-group", "chip-group"] },
|
|
45
|
+
"array": {
|
|
46
|
+
"primary": "tag-input",
|
|
47
|
+
"compatible": ["tag-input"],
|
|
48
|
+
"byItemsType": {
|
|
49
|
+
"string": { "primary": "tag-input", "compatible": ["tag-input"] },
|
|
50
|
+
"enum": { "primary": "multi-select", "compatible": ["multi-select"] }
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"datetime": {
|
|
54
|
+
"primary": null,
|
|
55
|
+
"compatible": [],
|
|
56
|
+
"byFormat": {
|
|
57
|
+
"date": { "primary": "date-picker", "compatible": ["date-picker"] },
|
|
58
|
+
"date-time": { "primary": "datetime-picker", "compatible": ["datetime-picker"] },
|
|
59
|
+
"time": { "primary": "time-picker", "compatible": ["time-picker"] },
|
|
60
|
+
"duration": { "primary": null, "compatible": [] }
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"object": { "primary": null, "compatible": [] },
|
|
64
|
+
"relation": { "primary": "entity-picker", "compatible": ["entity-picker"] },
|
|
65
|
+
"user": { "primary": "user-picker", "compatible": ["user-picker"] },
|
|
66
|
+
"currency": { "primary": "currency", "compatible": ["currency"] },
|
|
67
|
+
"knowledge-text": { "primary": "knowledge-text", "compatible": ["knowledge-text"] },
|
|
68
|
+
"file": { "primary": "file", "compatible": ["file"] }
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import registry from './control-registry.json' with { type: 'json' }
|
|
2
|
+
|
|
3
|
+
/* =========================================================================
|
|
4
|
+
Field control registry — source of truth: ./control-registry.json
|
|
5
|
+
(which is also the input to scripts/codegen/page-layout-registry, so
|
|
6
|
+
the Go validator and the TS renderer agree on every slug).
|
|
7
|
+
|
|
8
|
+
Two surfaces:
|
|
9
|
+
|
|
10
|
+
- `BUILT_IN_CONTROLS` : the slug allow-list shipped by
|
|
11
|
+
@proteos/ui's PageLayoutRenderer.
|
|
12
|
+
- `lookupControls(attr)` : per-(type+format|items.type) bucket.
|
|
13
|
+
`lookupPrimaryControl` : the bucket's primary (renderer dispatch).
|
|
14
|
+
`lookupCompatibleControls` : the bucket's compatible list (inspector
|
|
15
|
+
picker).
|
|
16
|
+
|
|
17
|
+
Resolution walks the discriminator chain: type → byFormat[meta.format]
|
|
18
|
+
for `string` and `datetime`, type → byItemsType[meta.items.type] for
|
|
19
|
+
`array`. Falls back to the type-level entry when no narrower bucket
|
|
20
|
+
matches. A null primary with empty compatible signals "render-only
|
|
21
|
+
fallback" (see plan §3.2.5).
|
|
22
|
+
========================================================================= */
|
|
23
|
+
|
|
24
|
+
export const BUILT_IN_CONTROLS = registry.builtInControls as readonly string[]
|
|
25
|
+
export type BuiltInControlSlug = (typeof BUILT_IN_CONTROLS)[number]
|
|
26
|
+
|
|
27
|
+
export interface ControlBucket {
|
|
28
|
+
readonly primary: string | null
|
|
29
|
+
readonly compatible: readonly string[]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface ControlBucketJson extends ControlBucket {
|
|
33
|
+
readonly byFormat?: Readonly<Record<string, ControlBucketJson>>
|
|
34
|
+
readonly byItemsType?: Readonly<Record<string, ControlBucketJson>>
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const CONTROLS = registry.controls as Readonly<Record<string, ControlBucketJson>>
|
|
38
|
+
|
|
39
|
+
/** True when `slug` matches a built-in control. */
|
|
40
|
+
export function isBuiltInControl(slug: string): boolean {
|
|
41
|
+
return (BUILT_IN_CONTROLS as readonly string[]).includes(slug)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Minimal Attribute shape the lookup helpers need. The SDK's full
|
|
46
|
+
* `Attribute` type extends this; consumers can pass either.
|
|
47
|
+
*/
|
|
48
|
+
export interface AttributeForLookup {
|
|
49
|
+
type: string
|
|
50
|
+
meta?: {
|
|
51
|
+
format?: string
|
|
52
|
+
items?: { type?: string }
|
|
53
|
+
} | null
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Resolves the full ControlBucket for an attribute. Walks
|
|
58
|
+
* type → byFormat[meta.format] (string/datetime) or
|
|
59
|
+
* type → byItemsType[meta.items.type] (array), falling back to the
|
|
60
|
+
* type-level entry.
|
|
61
|
+
*
|
|
62
|
+
* Returns `{ primary: null, compatible: [] }` when neither the type
|
|
63
|
+
* nor any narrower bucket matches — including when the attribute type
|
|
64
|
+
* is unknown to the registry (e.g. legacy wire data).
|
|
65
|
+
*/
|
|
66
|
+
export function lookupControls(attr: AttributeForLookup): ControlBucket {
|
|
67
|
+
const typeBucket = CONTROLS[attr.type]
|
|
68
|
+
if (!typeBucket) return EMPTY
|
|
69
|
+
|
|
70
|
+
const meta = attr.meta ?? undefined
|
|
71
|
+
const format = meta?.format
|
|
72
|
+
if (format && typeBucket.byFormat?.[format]) {
|
|
73
|
+
return typeBucket.byFormat[format]
|
|
74
|
+
}
|
|
75
|
+
const itemsType = meta?.items?.type
|
|
76
|
+
if (itemsType && typeBucket.byItemsType?.[itemsType]) {
|
|
77
|
+
return typeBucket.byItemsType[itemsType]
|
|
78
|
+
}
|
|
79
|
+
return typeBucket
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Convenience: the primary slug, or null for the read-only fallback. */
|
|
83
|
+
export function lookupPrimaryControl(attr: AttributeForLookup): string | null {
|
|
84
|
+
return lookupControls(attr).primary
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Convenience: the compatible slug list (empty for the read-only fallback). */
|
|
88
|
+
export function lookupCompatibleControls(attr: AttributeForLookup): readonly string[] {
|
|
89
|
+
return lookupControls(attr).compatible
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const EMPTY: ControlBucket = { primary: null, compatible: [] }
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import { type FilterGroup, FilterGroupSchema } from '../filters.js'
|
|
3
|
+
import {
|
|
4
|
+
type CommonProps,
|
|
5
|
+
commonPropsShape,
|
|
6
|
+
layoutAlignShape,
|
|
7
|
+
layoutGapShape,
|
|
8
|
+
layoutJustifyShape,
|
|
9
|
+
} from './common-props.js'
|
|
10
|
+
|
|
11
|
+
export const LayoutElementType = {
|
|
12
|
+
Row: 'row',
|
|
13
|
+
Column: 'column',
|
|
14
|
+
Section: 'section',
|
|
15
|
+
Tabs: 'tabs',
|
|
16
|
+
Field: 'field',
|
|
17
|
+
RelatedList: 'related_list',
|
|
18
|
+
Component: 'component',
|
|
19
|
+
Divider: 'divider',
|
|
20
|
+
Text: 'text',
|
|
21
|
+
} as const
|
|
22
|
+
export type LayoutElementType = (typeof LayoutElementType)[keyof typeof LayoutElementType]
|
|
23
|
+
|
|
24
|
+
export type RowElement = CommonProps & {
|
|
25
|
+
type: 'row'
|
|
26
|
+
gap?: 'xs' | 'sm' | 'md' | 'lg'
|
|
27
|
+
/** When true (default), children flow to the next line if they don't fit. */
|
|
28
|
+
allows_wrap?: boolean
|
|
29
|
+
align?: 'start' | 'center' | 'end' | 'stretch'
|
|
30
|
+
justify?: 'start' | 'center' | 'end' | 'between' | 'around'
|
|
31
|
+
children: LayoutElement[]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type ColumnElement = CommonProps & {
|
|
35
|
+
type: 'column'
|
|
36
|
+
gap?: 'xs' | 'sm' | 'md' | 'lg'
|
|
37
|
+
align?: 'start' | 'center' | 'end' | 'stretch'
|
|
38
|
+
justify?: 'start' | 'center' | 'end' | 'between' | 'around'
|
|
39
|
+
children: LayoutElement[]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type SectionElement = CommonProps & {
|
|
43
|
+
type: 'section'
|
|
44
|
+
title?: string
|
|
45
|
+
description?: string
|
|
46
|
+
is_collapsible?: boolean
|
|
47
|
+
default_collapsed?: boolean
|
|
48
|
+
content: LayoutElement
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export type LayoutTab = {
|
|
52
|
+
id: string
|
|
53
|
+
label: string
|
|
54
|
+
icon?: string
|
|
55
|
+
visible_when?: FilterGroup
|
|
56
|
+
content: LayoutElement
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export type TabsElement = CommonProps & {
|
|
60
|
+
type: 'tabs'
|
|
61
|
+
tabs: LayoutTab[]
|
|
62
|
+
default_tab_id?: string
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export type FieldElement = CommonProps & {
|
|
66
|
+
type: 'field'
|
|
67
|
+
attribute: string
|
|
68
|
+
label?: string | null
|
|
69
|
+
description?: string
|
|
70
|
+
placeholder?: string
|
|
71
|
+
is_read_only?: boolean
|
|
72
|
+
is_required?: boolean
|
|
73
|
+
empty_display?: 'dash' | 'hide' | string
|
|
74
|
+
control?: string
|
|
75
|
+
control_props?: Record<string, unknown>
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Lists records of `related_entity_slug` that reference the current record
|
|
80
|
+
* through the `via_attribute` relation attribute. Replaces the pre-LUM-20
|
|
81
|
+
* `relationshipId` reference — the relation is identified directly by the
|
|
82
|
+
* attribute on the host entity. `list_slug` optionally pins which list
|
|
83
|
+
* definition drives the column / sort / filter model; when omitted, the
|
|
84
|
+
* renderer falls back to the first list configured for the related entity.
|
|
85
|
+
*/
|
|
86
|
+
export type RelatedListElement = CommonProps & {
|
|
87
|
+
type: 'related_list'
|
|
88
|
+
related_entity_slug: string
|
|
89
|
+
via_attribute: string
|
|
90
|
+
list_slug?: string
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export type ComponentElement = CommonProps & {
|
|
94
|
+
type: 'component'
|
|
95
|
+
component_slug: string
|
|
96
|
+
props?: Record<string, unknown>
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export type DividerElement = CommonProps & {
|
|
100
|
+
type: 'divider'
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export type TextVariant = 'heading' | 'subheading' | 'body' | 'caption' | 'callout'
|
|
104
|
+
|
|
105
|
+
export type TextElement = CommonProps & {
|
|
106
|
+
type: 'text'
|
|
107
|
+
variant: TextVariant
|
|
108
|
+
content: string
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export type LayoutElement =
|
|
112
|
+
| RowElement
|
|
113
|
+
| ColumnElement
|
|
114
|
+
| SectionElement
|
|
115
|
+
| TabsElement
|
|
116
|
+
| FieldElement
|
|
117
|
+
| RelatedListElement
|
|
118
|
+
| ComponentElement
|
|
119
|
+
| DividerElement
|
|
120
|
+
| TextElement
|
|
121
|
+
|
|
122
|
+
// ──────────────────────────────────────────────────────────── Schemas ──
|
|
123
|
+
|
|
124
|
+
export const LayoutElementSchema: z.ZodType<LayoutElement> = z.lazy(() =>
|
|
125
|
+
z.discriminatedUnion('type', [
|
|
126
|
+
z.object({
|
|
127
|
+
type: z.literal('row'),
|
|
128
|
+
...commonPropsShape,
|
|
129
|
+
gap: layoutGapShape.optional(),
|
|
130
|
+
allows_wrap: z.boolean().optional(),
|
|
131
|
+
align: layoutAlignShape.optional(),
|
|
132
|
+
justify: layoutJustifyShape.optional(),
|
|
133
|
+
children: z.array(LayoutElementSchema),
|
|
134
|
+
}),
|
|
135
|
+
z.object({
|
|
136
|
+
type: z.literal('column'),
|
|
137
|
+
...commonPropsShape,
|
|
138
|
+
gap: layoutGapShape.optional(),
|
|
139
|
+
align: layoutAlignShape.optional(),
|
|
140
|
+
justify: layoutJustifyShape.optional(),
|
|
141
|
+
children: z.array(LayoutElementSchema),
|
|
142
|
+
}),
|
|
143
|
+
z.object({
|
|
144
|
+
type: z.literal('section'),
|
|
145
|
+
...commonPropsShape,
|
|
146
|
+
title: z.string().optional(),
|
|
147
|
+
description: z.string().optional(),
|
|
148
|
+
is_collapsible: z.boolean().optional(),
|
|
149
|
+
default_collapsed: z.boolean().optional(),
|
|
150
|
+
content: LayoutElementSchema,
|
|
151
|
+
}),
|
|
152
|
+
z.object({
|
|
153
|
+
type: z.literal('tabs'),
|
|
154
|
+
...commonPropsShape,
|
|
155
|
+
tabs: z.array(
|
|
156
|
+
z.object({
|
|
157
|
+
id: z.string().min(1),
|
|
158
|
+
label: z.string().min(1),
|
|
159
|
+
icon: z.string().optional(),
|
|
160
|
+
visible_when: FilterGroupSchema.optional(),
|
|
161
|
+
content: LayoutElementSchema,
|
|
162
|
+
}),
|
|
163
|
+
),
|
|
164
|
+
default_tab_id: z.string().optional(),
|
|
165
|
+
}),
|
|
166
|
+
z.object({
|
|
167
|
+
type: z.literal('field'),
|
|
168
|
+
...commonPropsShape,
|
|
169
|
+
attribute: z.string().min(1),
|
|
170
|
+
label: z.string().nullable().optional(),
|
|
171
|
+
description: z.string().optional(),
|
|
172
|
+
placeholder: z.string().optional(),
|
|
173
|
+
is_read_only: z.boolean().optional(),
|
|
174
|
+
is_required: z.boolean().optional(),
|
|
175
|
+
empty_display: z.string().optional(),
|
|
176
|
+
control: z.string().optional(),
|
|
177
|
+
control_props: z.record(z.unknown()).optional(),
|
|
178
|
+
}),
|
|
179
|
+
z.object({
|
|
180
|
+
type: z.literal('related_list'),
|
|
181
|
+
...commonPropsShape,
|
|
182
|
+
related_entity_slug: z.string().min(1),
|
|
183
|
+
via_attribute: z.string().min(1),
|
|
184
|
+
list_slug: z.string().min(1).optional(),
|
|
185
|
+
}),
|
|
186
|
+
z.object({
|
|
187
|
+
type: z.literal('component'),
|
|
188
|
+
...commonPropsShape,
|
|
189
|
+
component_slug: z.string().min(1),
|
|
190
|
+
props: z.record(z.unknown()).optional(),
|
|
191
|
+
}),
|
|
192
|
+
z.object({
|
|
193
|
+
type: z.literal('divider'),
|
|
194
|
+
...commonPropsShape,
|
|
195
|
+
}),
|
|
196
|
+
z.object({
|
|
197
|
+
type: z.literal('text'),
|
|
198
|
+
...commonPropsShape,
|
|
199
|
+
variant: z.enum(['heading', 'subheading', 'body', 'caption', 'callout']),
|
|
200
|
+
content: z.string().min(1),
|
|
201
|
+
}),
|
|
202
|
+
]),
|
|
203
|
+
) as unknown as z.ZodType<LayoutElement>
|