@stndrds/schema 1.0.0-alpha.168 → 1.0.0-alpha.170

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 (51) hide show
  1. package/dist/{filters-zzsF0GxK.d.ts → filters-B2cCCbDq.d.ts} +7 -4
  2. package/dist/{filters-DRXk4dLI.d.mts → filters-B9Pjped4.d.mts} +7 -4
  3. package/dist/{helpers-BTuRte-r.d.mts → helpers-YWZowk1B.d.mts} +3 -3
  4. package/dist/{helpers-D3nsZLoE.d.ts → helpers-icxxQQJQ.d.ts} +3 -3
  5. package/dist/index.d.mts +91 -21
  6. package/dist/index.d.ts +91 -21
  7. package/dist/index.js +102 -68
  8. package/dist/index.mjs +98 -70
  9. package/dist/{types-Bemfgle3.d.ts → types-DGGecyHV.d.ts} +1 -1
  10. package/dist/{types-DxEobsMy.d.mts → types-DqpxKOcD.d.mts} +1 -1
  11. package/dist/validation/all.d.mts +3 -3
  12. package/dist/validation/all.d.ts +3 -3
  13. package/dist/validation/all.js +4 -0
  14. package/dist/validation/all.mjs +1 -1
  15. package/dist/validation/complex/currency.d.mts +2 -2
  16. package/dist/validation/complex/currency.d.ts +2 -2
  17. package/dist/validation/complex/file.d.mts +2 -2
  18. package/dist/validation/complex/file.d.ts +2 -2
  19. package/dist/validation/complex/location.d.mts +2 -2
  20. package/dist/validation/complex/location.d.ts +2 -2
  21. package/dist/validation/complex/phone.d.mts +2 -2
  22. package/dist/validation/complex/phone.d.ts +2 -2
  23. package/dist/validation/complex/relation.d.mts +2 -2
  24. package/dist/validation/complex/relation.d.ts +2 -2
  25. package/dist/validation/complex/richtext.d.mts +2 -2
  26. package/dist/validation/complex/richtext.d.ts +2 -2
  27. package/dist/validation/complex/select.d.mts +2 -2
  28. package/dist/validation/complex/select.d.ts +2 -2
  29. package/dist/validation/complex/user.d.mts +2 -2
  30. package/dist/validation/complex/user.d.ts +2 -2
  31. package/dist/validation/computed/formula.d.mts +2 -2
  32. package/dist/validation/computed/formula.d.ts +2 -2
  33. package/dist/validation/computed/rollup.d.mts +2 -2
  34. package/dist/validation/computed/rollup.d.ts +2 -2
  35. package/dist/validation/config/index.d.mts +1 -1
  36. package/dist/validation/config/index.d.ts +1 -1
  37. package/dist/validation/core/index.d.mts +3 -3
  38. package/dist/validation/core/index.d.ts +3 -3
  39. package/dist/validation/object/index.d.mts +3 -3
  40. package/dist/validation/object/index.d.ts +3 -3
  41. package/dist/validation/primitives/checkbox.d.mts +2 -2
  42. package/dist/validation/primitives/checkbox.d.ts +2 -2
  43. package/dist/validation/primitives/date.d.mts +2 -2
  44. package/dist/validation/primitives/date.d.ts +2 -2
  45. package/dist/validation/primitives/number.d.mts +2 -2
  46. package/dist/validation/primitives/number.d.ts +2 -2
  47. package/dist/validation/primitives/rating.d.mts +2 -2
  48. package/dist/validation/primitives/rating.d.ts +2 -2
  49. package/dist/validation/primitives/text.d.mts +2 -2
  50. package/dist/validation/primitives/text.d.ts +2 -2
  51. package/package.json +2 -2
package/dist/index.d.ts CHANGED
@@ -1,15 +1,15 @@
1
- import { k as SortRule, l as FilterState, m as Timestamps, n as AttributeType, V as ViewType, o as ViewConfig, p as ConfigOverrides, j as CompletionStatus, A as Attribute, q as LocationGranularity, r as Location, e as FormulaAttribute, f as RollupAttribute, d as StatusAttribute, c as SelectAttribute, b as MultiselectAttribute, s as Phone, t as Currency, u as ObjectRecord, D as DateAttribute, U as UserAttribute, v as DocumentAttribute, w as DocumentSlotConfig, x as FeatureGate, g as CheckboxAttribute, C as CurrencyAttribute, F as FileAttribute, y as FormulaReturnType, L as LocationAttribute, z as Option, N as NumberAttribute, P as PhoneAttribute, h as RatingAttribute, R as RelationAttribute, i as TextAttribute, T as TextAreaAttribute, B as BilateralConfig, S as SingleRelationAttribute, M as MultiRelationAttribute, E as RelationTarget, a as RichtextAttribute, G as RichtextFeature, H as RollupFunction, I as MigrationDefinition, O as ObjectDefinition, J as DetailViewConfig, K as DetailViewDefinition, Q as DetailViewLayout, W as SidePanelConfig, X as Field, Y as AttributeGroupField, Z as FieldGroup, _ as RelationGroup, $ as Group, a0 as TableTab, a1 as CreateMode, a2 as Tab, a3 as ListViewConfig, a4 as ListViewDefinition, a5 as FlagValueType, a6 as FeatureFlagDefinition, a7 as FlagLevel, a8 as FeatureFlagsRepository, a9 as StaticFlagDefault, aa as ResolvedFlag, ab as ViewDefinition, ac as ListViewTab, ad as FilterOperator, ae as FilterValue } from './filters-zzsF0GxK.js';
2
- export { af as ActivityTab, ag as AdvancedFilterState, ah as AttributeGroup, ai as BaseAttribute, aj as BuiltInTransform, ak as CreateDocument, al as CreateDocumentSlot, am as CreateProcessingJob, an as CurrencyFilterValue, ao as CustomTab, ap as DEFAULT_DOCUMENT_SLOT, aq as DateFormat, ar as DateValue, as as Document, at as DocumentListOptions, au as DocumentSlot, av as DocumentWithSlots, aw as DocumentsTab, ax as ExtendedFilterRule, ay as FeatureFlagsConfig, az as FilterCombinator, aA as FilterGroup, aB as FilterRule, aC as FlagOverride, aD as FormDensity, aE as FormTab, aF as FormsTab, aG as InverseSource, aH as ListViewLayout, aI as MigrationError, aJ as NO_VALUE_OPERATORS, aK as NoValueOperator, aL as NumberUnit, aM as OPERATORS_BY_TYPE, aN as ObjectAttribute, aO as OptionPropertyAttribute, aP as PhoneFilterValue, aQ as ProcessingJob, aR as ProcessingJobStatus, aS as ProcessingJobType, aT as PropertyAttribute, aU as PropertySchema, aV as PropertyType, aW as QueryState, aX as RELATION_TARGET_ANY, aY as RESERVED_ATTRIBUTE_NAMES, aZ as RecordDocuments, a_ as RelationSource, a$ as RelativeDateValue, b0 as ReservedAttributeName, b1 as RichtextTab, b2 as SYSTEM_FIELD_NAMES, b3 as SchemaOperation, b4 as SchemaTransform, b5 as SlotStatus, b6 as SortDirection, b7 as StatusGroup, b8 as SystemFieldName, b9 as TabType, ba as TableSource, bb as TransformSource, bc as UpdateDocument, bd as UpdateDocumentSlot, be as UpdateProcessingJob, bf as ViewOperation, bg as ViewOverlay, bh as ViewTransform, bi as getRollupFilterOperators, bj as hasOptions, bk as inferInverseCardinality, bl as isAttributeSortable, bm as isBilateralRelation, bn as isDetailView, bo as isFieldGroup, bp as isListView, bq as isNoValueOperator, br as isRelationGroup, bs as isUniversalRelation } from './filters-zzsF0GxK.js';
1
+ import { k as SortRule, l as FilterState, m as Timestamps, n as AttributeType, V as ViewType, o as ViewConfig, p as ConfigOverrides, j as CompletionStatus, A as Attribute, q as LocationGranularity, r as Location, e as FormulaAttribute, f as RollupAttribute, s as DocumentAttribute, d as StatusAttribute, c as SelectAttribute, b as MultiselectAttribute, t as Phone, u as Currency, v as ObjectRecord, D as DateAttribute, U as UserAttribute, w as DocumentSlotConfig, x as PropertySchema, y as FeatureGate, g as CheckboxAttribute, C as CurrencyAttribute, i as TextAttribute, T as TextAreaAttribute, N as NumberAttribute, P as PhoneAttribute, z as Option, h as RatingAttribute, L as LocationAttribute, F as FileAttribute, B as FormulaReturnType, R as RelationAttribute, E as BilateralConfig, S as SingleRelationAttribute, M as MultiRelationAttribute, G as RelationTarget, a as RichtextAttribute, H as RichtextFeature, I as RollupFunction, J as MigrationDefinition, O as ObjectDefinition, K as DetailViewConfig, Q as DetailViewDefinition, W as DetailViewLayout, X as SidePanelConfig, Y as Field, Z as AttributeGroupField, _ as FieldGroup, $ as RelationGroup, a0 as Group, a1 as TableTab, a2 as CreateMode, a3 as Tab, a4 as ListViewConfig, a5 as ListViewDefinition, a6 as FlagValueType, a7 as FeatureFlagDefinition, a8 as FlagLevel, a9 as FeatureFlagsRepository, aa as StaticFlagDefault, ab as ResolvedFlag, ac as ViewDefinition, ad as ListViewTab, ae as FilterOperator, af as FilterValue } from './filters-B2cCCbDq.js';
2
+ export { ag as ActivityTab, ah as AdvancedFilterState, ai as AttributeGroup, aj as BaseAttribute, ak as BuiltInTransform, al as CreateDocument, am as CreateDocumentSlot, an as CreateProcessingJob, ao as CurrencyFilterValue, ap as CustomTab, aq as DEFAULT_DOCUMENT_SLOT, ar as DateFormat, as as DateValue, at as Document, au as DocumentListOptions, av as DocumentSlot, aw as DocumentWithSlots, ax as DocumentsTab, ay as ExtendedFilterRule, az as FeatureFlagsConfig, aA as FilterCombinator, aB as FilterGroup, aC as FilterRule, aD as FlagOverride, aE as FormDensity, aF as FormTab, aG as FormsTab, aH as InverseSource, aI as ListViewLayout, aJ as MigrationError, aK as NO_VALUE_OPERATORS, aL as NoValueOperator, aM as NumberUnit, aN as OPERATORS_BY_TYPE, aO as ObjectAttribute, aP as OptionPropertyAttribute, aQ as PhoneFilterValue, aR as ProcessingJob, aS as ProcessingJobStatus, aT as ProcessingJobType, aU as PropertyAttribute, aV as PropertyType, aW as QueryState, aX as RELATION_TARGET_ANY, aY as RESERVED_ATTRIBUTE_NAMES, aZ as RecordDocuments, a_ as RelationSource, a$ as RelativeDateValue, b0 as ReservedAttributeName, b1 as RichtextTab, b2 as SYSTEM_FIELD_NAMES, b3 as SchemaOperation, b4 as SchemaTransform, b5 as SlotStatus, b6 as SortDirection, b7 as StatusGroup, b8 as SystemFieldName, b9 as TabType, ba as TableSource, bb as TransformSource, bc as UpdateDocument, bd as UpdateDocumentSlot, be as UpdateProcessingJob, bf as ViewOperation, bg as ViewOverlay, bh as ViewTransform, bi as getRollupFilterOperators, bj as hasOptions, bk as inferInverseCardinality, bl as isAttributeSortable, bm as isBilateralRelation, bn as isDetailView, bo as isFieldGroup, bp as isListView, bq as isNoValueOperator, br as isRelationGroup, bs as isUniversalRelation } from './filters-B2cCCbDq.js';
3
3
  import { MimeType, IconName, ColorId, CountryIso3, CurrencyCode } from '@stndrds/constants';
4
4
  import { Uuid, TenantId } from './utils.js';
5
5
  export { UserId, asTenantId, asUserId, deepEqual, generateId, indexBy } from './utils.js';
6
6
  import { StandardSchemaV1 } from '@standard-schema/spec';
7
7
  export { StandardSchemaV1 } from '@standard-schema/spec';
8
8
  import z from 'zod';
9
- export { V as ValidationMessages } from './types-Bemfgle3.js';
9
+ export { V as ValidationMessages } from './types-DGGecyHV.js';
10
10
  export { DEFAULT_VALIDATION_MESSAGES, formatZodErrors } from './validation/core/index.js';
11
11
  export { parseAttributeConfig } from './validation/config/index.js';
12
- export { c as computeRecordStatus, a as createFormAttributeValidator, v as validateDraftOrThrow, b as validateObject, d as validateObjectOrThrow } from './helpers-D3nsZLoE.js';
12
+ export { c as computeRecordStatus, a as createFormAttributeValidator, v as validateDraft, b as validateDraftOrThrow, d as validateObject, e as validateObjectOrThrow } from './helpers-icxxQQJQ.js';
13
13
 
14
14
  /**
15
15
  * Generic list options for pagination and sorting
@@ -2467,12 +2467,51 @@ type InferSelectValue<A extends SelectAttribute> = A["options"] extends readonly
2467
2467
  type InferMultiselectValue<A extends MultiselectAttribute> = A["options"] extends readonly {
2468
2468
  value: infer V;
2469
2469
  }[] ? V[] : string[];
2470
+ /**
2471
+ * @internal — implementation detail of DocumentAttributeBuilder.qualifyWith().
2472
+ *
2473
+ * Phantom brand carrying typed props into the type system without changing
2474
+ * the runtime attribute shape. `TProps` is `{ [propName]?: value | null }`
2475
+ * inferred from the builders passed to .qualifyWith(). `TMultiple` tracks
2476
+ * whether .multiple() was called.
2477
+ */
2478
+ interface QualifiedDocumentBrand<TProps extends Record<string, unknown>, TMultiple extends boolean> {
2479
+ readonly __qualifiedDocumentProps: TProps;
2480
+ readonly __qualifiedDocumentMultiple: TMultiple;
2481
+ }
2482
+ /**
2483
+ * @internal — used by DocumentAttributeBuilder.qualifyWith().
2484
+ *
2485
+ * Infers the props shape from a tuple of PropertyAttributeBuilders.
2486
+ * Each builder contributes `{ [name]?: value | null }` to the result.
2487
+ */
2488
+ type InferQualifiedProps<TBuilders extends readonly unknown[]> = {
2489
+ [B in TBuilders[number] as B extends {
2490
+ $infer: {
2491
+ value: unknown;
2492
+ };
2493
+ } & {
2494
+ _types: {
2495
+ name: infer N extends string;
2496
+ };
2497
+ } ? N : never]?: (B extends {
2498
+ $infer: {
2499
+ value: infer V;
2500
+ };
2501
+ } ? V : never) | null;
2502
+ };
2470
2503
  /**
2471
2504
  * Maps an Attribute type to its runtime value type
2472
2505
  * Uses a flat lookup table + 3 special cases for option-based attributes
2473
2506
  * This avoids deep conditional nesting that causes TS2589 on large objects
2474
2507
  */
2475
- type InferAttributeValue<A extends Attribute> = A extends StatusAttribute ? InferStatusValue<A> : A extends SelectAttribute ? InferSelectValue<A> : A extends MultiselectAttribute ? InferMultiselectValue<A> : A["type"] extends keyof AttributeValueMap ? AttributeValueMap[A["type"]] : unknown;
2508
+ type InferAttributeValue<A extends Attribute> = A extends DocumentAttribute & QualifiedDocumentBrand<infer TProps, infer TMultiple> ? TMultiple extends true ? Array<{
2509
+ id: string;
2510
+ props: TProps;
2511
+ }> : {
2512
+ id: string;
2513
+ props: TProps;
2514
+ } : A extends StatusAttribute ? InferStatusValue<A> : A extends SelectAttribute ? InferSelectValue<A> : A extends MultiselectAttribute ? InferMultiselectValue<A> : A["type"] extends keyof AttributeValueMap ? AttributeValueMap[A["type"]] : unknown;
2476
2515
  /**
2477
2516
  * Base type for custom attribute values added via UI
2478
2517
  * Supports all possible attribute value types
@@ -3150,6 +3189,26 @@ declare class DocumentSlotValidationError extends Error {
3150
3189
  }
3151
3190
  declare function validateSlotAgainstConfig(slotName: string, mimeType: string, slots: DocumentSlotConfig[]): DocumentSlotConfig;
3152
3191
 
3192
+ /**
3193
+ * The set of attribute types allowed as relation/document properties.
3194
+ * This is the complement of the internal FORBIDDEN_PROPERTY_TYPES list.
3195
+ */
3196
+ declare const ALLOWED_PROPERTY_TYPES: readonly ["text", "textarea", "number", "checkbox", "date", "phone", "currency", "status", "select", "multiselect", "rating", "location"];
3197
+ interface BuilderLike {
3198
+ build(): {
3199
+ type: string;
3200
+ name: string;
3201
+ };
3202
+ }
3203
+ /**
3204
+ * Validates and builds a PropertySchema from an array of attribute builders.
3205
+ * Throws if any builder produces a forbidden attribute type.
3206
+ *
3207
+ * Preserved error message (byte-equivalent with RelationAttributeBuilder.qualifyWith):
3208
+ * `Property type "<type>" is not supported in .qualifyWith()`
3209
+ */
3210
+ declare function buildPropertySchema(builders: BuilderLike[]): PropertySchema;
3211
+
3153
3212
  /**
3154
3213
  * Default empty value placeholder
3155
3214
  */
@@ -4175,10 +4234,10 @@ declare function rollup<TName extends string>(config: TypedBuilderConfig<TName>)
4175
4234
  * .maxDocuments(10)
4176
4235
  * ```
4177
4236
  */
4178
- declare class DocumentAttributeBuilder<TName extends string, TRequired extends boolean = false> extends BaseAttributeBuilder<DocumentAttribute> {
4237
+ declare class DocumentAttributeBuilder<TName extends string, TRequired extends boolean = false, TProps extends Record<string, unknown> = never, TMultiple extends boolean = false> extends BaseAttributeBuilder<DocumentAttribute> {
4179
4238
  readonly _types: {
4180
4239
  name: TName;
4181
- attribute: DocumentAttribute;
4240
+ attribute: [TProps] extends [never] ? DocumentAttribute : DocumentAttribute & QualifiedDocumentBrand<TProps, TMultiple>;
4182
4241
  required: TRequired;
4183
4242
  };
4184
4243
  /**
@@ -4187,16 +4246,22 @@ declare class DocumentAttributeBuilder<TName extends string, TRequired extends b
4187
4246
  */
4188
4247
  readonly $infer: {
4189
4248
  /** The runtime value type for this attribute (document ID or array of IDs) */
4190
- value: string | string[];
4249
+ value: [TProps] extends [never] ? string | string[] : TMultiple extends true ? Array<{
4250
+ id: string;
4251
+ props: TProps;
4252
+ }> : {
4253
+ id: string;
4254
+ props: TProps;
4255
+ };
4191
4256
  /** The full attribute definition type */
4192
4257
  definition: DocumentAttribute;
4193
4258
  };
4194
4259
  constructor(name: TName, label: string);
4195
4260
  /**
4196
4261
  * Allow multiple documents.
4197
- * Value becomes string[] instead of string.
4262
+ * Value becomes string[] instead of string (or Array<{ id; props }> when qualified).
4198
4263
  */
4199
- multiple(): this;
4264
+ multiple(): DocumentAttributeBuilder<TName, TRequired, TProps, true>;
4200
4265
  /**
4201
4266
  * Maximum number of documents (only applies when multiple: true).
4202
4267
  */
@@ -4222,14 +4287,27 @@ declare class DocumentAttributeBuilder<TName extends string, TRequired extends b
4222
4287
  attribute<TAttr extends Attribute>(builder: {
4223
4288
  build(): TAttr;
4224
4289
  }): this;
4290
+ /**
4291
+ * Add properties to qualify each document using existing attribute builders.
4292
+ * Returns a new builder type that carries the inferred props shape for $infer.
4293
+ *
4294
+ * @example
4295
+ * document({ name: "contracts", label: "Contracts" })
4296
+ * .multiple()
4297
+ * .qualifyWith(
4298
+ * select({ name: "kind", label: "Kind" }).options([...]),
4299
+ * number({ name: "amount", label: "Amount" }).min(0),
4300
+ * )
4301
+ */
4302
+ qualifyWith<const TBuilders extends readonly PropertyAttributeBuilder[]>(...builders: TBuilders): DocumentAttributeBuilder<TName, TRequired, InferQualifiedProps<TBuilders>, TMultiple>;
4225
4303
  /**
4226
4304
  * Mark this attribute as required.
4227
4305
  */
4228
- required(): DocumentAttributeBuilder<TName, true>;
4306
+ required(): DocumentAttributeBuilder<TName, true, TProps, TMultiple>;
4229
4307
  /**
4230
4308
  * Mark this attribute as optional (undo required).
4231
4309
  */
4232
- optional(): DocumentAttributeBuilder<TName, false>;
4310
+ optional(): DocumentAttributeBuilder<TName, false, TProps, TMultiple>;
4233
4311
  }
4234
4312
  /**
4235
4313
  * Create a document attribute.
@@ -5176,10 +5254,6 @@ declare class DetailViewBuilder {
5176
5254
  * Build the final view definition
5177
5255
  */
5178
5256
  build(): DetailViewDefinition;
5179
- /**
5180
- * Validate view name format (kebab-case)
5181
- */
5182
- private validateName;
5183
5257
  }
5184
5258
  /**
5185
5259
  * Create a new detail view builder
@@ -5341,10 +5415,6 @@ declare class ListViewBuilder {
5341
5415
  * Build the final list view definition
5342
5416
  */
5343
5417
  build(): ListViewDefinition;
5344
- /**
5345
- * Validate view name format (kebab-case)
5346
- */
5347
- private validateName;
5348
5418
  }
5349
5419
  /**
5350
5420
  * Builder for configuring tabs in list views.
@@ -6483,4 +6553,4 @@ declare const OPERATOR_SPECS: Record<FilterOperator, OperatorSpec>;
6483
6553
  */
6484
6554
  declare function evaluateFilterState(state: FilterState, values: Record<string, unknown>, attributes: Attribute[]): boolean;
6485
6555
 
6486
- export { type AIAvailableModel, type AIBatchQuestion, type AIBatchQuestionAnswer, type AIBatchQuestionOption, type AIChatMessage, type AIChatMessagePart, type AIChatMessagePartType, type AICompactionSummary, type AIMemoryEntry, type AIMemoryType, type AIMessageRole, type AIProviderMetrics, type AIQuestion, type AIQuestionAnswer, type AIQuestionOption, type AIQuestionType, type AITodoItem, type AITodoList, type AITodoStatus, type AIToolCall, type AIToolCallStatus, type AIUsageMetrics, ALL_ACTIONS, ALL_SYSTEM_RESOURCES, type AccessAction, type AccessActionList, AccessDeniedError, type AccessLevel, type AccessPolicy, type AccessPolicyPreset, type AccessResourceType, type Action, ActivityTabConfig, type Actor, type ActorRoleAssignment, type ActorStatus, type ActorType, type AddAttributeInput, type AgentConfig, type AgentContextEntry, type AgentDashboard, type AgentDefinition, type AgentEvent, type AgentExecutionConfig, type AgentExecutionPolicy, type AgentMessageAttachment, type AgentMessagePart, type AgentQuestion, type AgentRun, type AgentRunStatus, type AgentSchedule, type AgentSession, type AgentSessionMessage, type AgentSessionMode, type AgentSessionStatus, type AgentToolCall, type AgentTriggerDefinition, type AgentTriggerType, type ApiKey, type ApiKeyAuthContext, type ApiKeyPermission, type ApiKeyWithSecret, type AssignActorRoleInput, type AssignRoleInput, Attribute, AttributeGroupField, AttributeInUseError, AttributeNotFoundError, AttributeType, type AttributeUsage, type AuditAction, type AuditActorType, type AuditChange, type AuditListOptions, type AuditLogEntry, type AuditResourceType, type AuditServiceOptions, type AuditSortField, BEHAVIOR_PROPERTIES, BilateralConfig, type BoundingBox, type BuilderConfig, CheckboxAttribute, CompletionStatus, ConcurrentModificationError, ConfigOverrides, type CountMode, type CreateActorInput, type CreateApiKeyInput, type CreateAuditLogInput, type CreateCustomObjectInput, type CreateDBAttribute, type CreateDBForm, type CreateDBFormSubmission, type CreateDBObject, type CreateDBView, type CreateDBViewOverlay, type CreateFile, CreateMode, type CreateObjectRecord, type CreatePermissionInput, type CreateRoleInput, type CreateSandboxExecution, type CreateUserProfile, type CreateViewInput, type CriticConfig, Currency, CurrencyAttribute, type CustomAttributeValue, CustomTabConfig, type DBAttribute, type DBForm, type DBFormSubmission, type DBObject, type DBView, type DBViewOverlay, DB_COLUMN_FIELDS, DEFAULT_ROLES, DEFAULT_ROLE_DESCRIPTIONS, DEFAULT_ROLE_LABELS, DEFAULT_ROLE_PERMISSIONS, DOCUMENT_SYSTEM_ATTRIBUTES, DateAttribute, type DefaultRoleName, DetailViewBuilder, DetailViewConfig, DetailViewDefinition, DetailViewLayout, DocumentAttribute, DocumentSlotConfig, DocumentSlotValidationError, DocumentsTabConfig, type DomainEvent, DuplicateError, EMPTY_VALUE_PLACEHOLDER, type EffectivePermissions, type EventDataMap, type EventType, type ExtractRecord, type ExtractRecordInput, type ExtractRecordInputStrict, type ExtractRecordStrict, type ExtractRecordUpdate, type ExtractRecordUpdateStrict, FORM_FORBIDDEN_ATTRIBUTE_TYPES, FeatureFlagDefinition, FeatureFlagsRepository, FeatureGate, Field, FieldGroup, type File, FileAttribute, type FileListOptions, type FileVisibility, FilterOperator, FilterState, FilterValue, FlagLevel, FlagRegistry, FlagService, FlagValueType, ForbiddenError, FormBuilder, type FormDefinition, type FormFieldRef, type FormFieldsRow, type FormFreeFieldRef, type FormHeadingRow, FormRegistry, type FormRow, FormRowBuilder, type FormSeparatorRow, type FormSlot, type FormSlotFieldRef, type FormStatus, type FormStep, FormStepBuilder, type FormSubmission, type FormSubmissionStatus, type FormSubmittedAgentEvent, type FormTextRow, FormulaAttribute, type FormulaResult, FormulaReturnType, type GeocodingAdapter, type GeocodingAutocompleteParams, type GeocodingParams, type GeocodingSuggestion, type GlobalSearchGroupedOptions, type GlobalSearchGroupedResult, type GlobalSearchOptions, type GlobalSearchResultItem, type GrantResourceAccessInput, Group, GroupBuilder, IDENTITY_PROPERTIES, type InferAttributeValue, InvalidPathError, type InviteUserInput, type ListOptions, ListViewBuilder, ListViewConfig, ListViewDefinition, ListViewTab, ListViewTabConfigBuilder, Location, LocationAttribute, LocationGranularity, MaxDepthExceededError, MemoryNotFoundError, type MentionEntityType, type MentionReference, type MentionedContext, type MentionedEntityContext, MigrationDefinition, type ModelDefinition, MultiRelationAttribute, MultiselectAttribute, NoopGeocodingAdapter, NotFoundError, NotImplementedError, NumberAttribute, OPERATOR_SPECS, ObjectBuilder, ObjectDefinition, ObjectNotFoundError, type ObjectPermissions, ObjectRecord, ObjectReferencedError, type OcrAdapter, type OcrInput, type OcrOptions, type OcrPage, type OcrResult, type OcrTextBlock, type OperatorSpec, Option, PRESENTATION_PROPERTIES, type PageInfo, type PageOptions, type PageResponse, type PathCardinality, type PathSegment, type PathSegmentType, type Permission, type PermissionScope, Phone, PhoneAttribute, type PolicyContext, PolicyViolationError, type PrincipalType, ProtectedResourceError, ProtectedRoleError, type ProviderName, type QuestionResponse, type QuestionStatus, RatingAttribute, type ReasoningPartData, type RecordAgentEvent, type RecordMetadata, RecordNotFoundError, type RecordPolicy, type RecordReference, RecordReferencedError, RelationAttribute, RelationGroup, RelationGroupBuilder, type RelationOption, type RelationOptionsResponse, RelationTarget, RepositoryError, type RepositoryOperation, ResolvedFlag, type ResourceAccess, type ResourceRef, type RetryPolicy, type ReverseGeocodingParams, RichtextAttribute, RichtextFeature, RichtextTabConfig, type Role, RoleNotFoundError, RollupAttribute, RollupFunction, STANDARD_SCHEMA_VENDOR, SYSTEM_ATTRIBUTES, SYSTEM_ATTRIBUTE_I18N_KEYS, SYSTEM_RESOURCES, SYSTEM_RESOURCE_LABELS, type SandboxExecution, type SandboxExecutionInput, type SandboxExecutionResult, type SandboxExecutionStatus, type SandboxMode, type SandboxTrigger, SchemaError, SchemaErrorCode, type SchemaResolver, type SearchOptions, SelectAttribute, SidePanelConfig, type SidebarExtraItem, SingleRelationAttribute, type SlotMode, SortRule, type SpecificAccessAction, type StandardSchemaIssue, type StandardSchemaResult, StaticFlagDefault, StatusAttribute, StorageError, type StorageOperation, type StorageProvider, type StreamEventCompactionEnd, type StreamEventCompactionFailed, type StreamEventCompactionStart, type StreamEventMessagePersisted, SyncError, type SystemAttribute, type SystemAttributeI18nKey, type SystemFields, type SystemPermissions, type SystemResource, Tab, TabBuilder, TableTab, TableTabConfig, TenantId, TextAreaAttribute, TextAttribute, type TextPartData, type ThinkingPartData, type TimeoutPolicy, Timestamps, type ToolPartData, type ToolPartState, type TriggerEventType, USER_STATUSES, type UpdateActorInput, type UpdateDBAttribute, type UpdateDBForm, type UpdateDBFormSubmission, type UpdateDBObject, type UpdateDBView, type UpdateDBViewOverlay, type UpdateFile, type UpdateObjectInput, type UpdateRoleInput, type UpdateUserProfile, type UpdateViewInput, type UpsertAccessPolicyInput, type UpsertDBAttribute, type UpsertDBObject, type UpsertDBView, UserAttribute, type UserProfile, type UserRoleAssignment, type UserStatus, Uuid, ValidationError, type ValidationErrorDetail, ViewConfig, ViewDefinition, ViewType, type WithCustomAttributes$1 as WithCustomAttributes, accessLevelToActions, actionsToAccessLevel, applyPipes, booleanFlag, checkbox, createFlagRegistry, createFlagService, createStandardSchemaProps, currency, date, detailView, document, evaluateFilterState, evaluateFormula, evaluateFormulaAttribute, evaluateFormulaWithResult, extractAttributeNames, extractFormulaVariables, extractRelationNames, extractRelationReferences, file, flagRegistry, flattenRelationsForEval, form, formRegistry, formatAttributeValue, formatFormulaResult, formula, generateDefaultDetailView, generateDefaultListView, getActiveTab, getErrorMessage, getPathDepth, getRelationPath, getSystemAttributeI18nKey, getSystemAttributeList, getTargetAttributeName, group, hasRelationReferences, isAttributeInUseError, isDefaultRole, isDocumentAttribute, isEmptyObject, isFormDefinition, isFormFieldsRow, isFormFreeFieldRef, isFormHeadingRow, isFormSeparatorRow, isFormSlotFieldRef, isFormTextRow, isLabelExpression, isNotEmpty, isNotFoundError, isObjectReferencedError, isProtectedResourceError, isRecordReferencedError, isSchemaError, isStandardSchema, isValidationError, jsonFlag, listView, location, matchesMime, multiselect, normaliseDocumentSlots, number, numberFlag, object, parsePath, pathHasManyCardinality, phone, rating, registry, relation, relationGroup, renderLabelExpression, resetViewToDefault, richtext, rollup, select, status, stringFlag, text, textarea, toUndefinedIfEmpty, user, validateAttributeName, validateFormulaExpression, validatePath, validateSlotAgainstConfig, viewRegistry };
6556
+ export { type AIAvailableModel, type AIBatchQuestion, type AIBatchQuestionAnswer, type AIBatchQuestionOption, type AIChatMessage, type AIChatMessagePart, type AIChatMessagePartType, type AICompactionSummary, type AIMemoryEntry, type AIMemoryType, type AIMessageRole, type AIProviderMetrics, type AIQuestion, type AIQuestionAnswer, type AIQuestionOption, type AIQuestionType, type AITodoItem, type AITodoList, type AITodoStatus, type AIToolCall, type AIToolCallStatus, type AIUsageMetrics, ALLOWED_PROPERTY_TYPES, ALL_ACTIONS, ALL_SYSTEM_RESOURCES, type AccessAction, type AccessActionList, AccessDeniedError, type AccessLevel, type AccessPolicy, type AccessPolicyPreset, type AccessResourceType, type Action, ActivityTabConfig, type Actor, type ActorRoleAssignment, type ActorStatus, type ActorType, type AddAttributeInput, type AgentConfig, type AgentContextEntry, type AgentDashboard, type AgentDefinition, type AgentEvent, type AgentExecutionConfig, type AgentExecutionPolicy, type AgentMessageAttachment, type AgentMessagePart, type AgentQuestion, type AgentRun, type AgentRunStatus, type AgentSchedule, type AgentSession, type AgentSessionMessage, type AgentSessionMode, type AgentSessionStatus, type AgentToolCall, type AgentTriggerDefinition, type AgentTriggerType, type ApiKey, type ApiKeyAuthContext, type ApiKeyPermission, type ApiKeyWithSecret, type AssignActorRoleInput, type AssignRoleInput, Attribute, AttributeGroupField, AttributeInUseError, AttributeNotFoundError, AttributeType, type AttributeUsage, type AuditAction, type AuditActorType, type AuditChange, type AuditListOptions, type AuditLogEntry, type AuditResourceType, type AuditServiceOptions, type AuditSortField, BEHAVIOR_PROPERTIES, BilateralConfig, type BoundingBox, type BuilderConfig, CheckboxAttribute, CompletionStatus, ConcurrentModificationError, ConfigOverrides, type CountMode, type CreateActorInput, type CreateApiKeyInput, type CreateAuditLogInput, type CreateCustomObjectInput, type CreateDBAttribute, type CreateDBForm, type CreateDBFormSubmission, type CreateDBObject, type CreateDBView, type CreateDBViewOverlay, type CreateFile, CreateMode, type CreateObjectRecord, type CreatePermissionInput, type CreateRoleInput, type CreateSandboxExecution, type CreateUserProfile, type CreateViewInput, type CriticConfig, Currency, CurrencyAttribute, type CustomAttributeValue, CustomTabConfig, type DBAttribute, type DBForm, type DBFormSubmission, type DBObject, type DBView, type DBViewOverlay, DB_COLUMN_FIELDS, DEFAULT_ROLES, DEFAULT_ROLE_DESCRIPTIONS, DEFAULT_ROLE_LABELS, DEFAULT_ROLE_PERMISSIONS, DOCUMENT_SYSTEM_ATTRIBUTES, DateAttribute, type DefaultRoleName, DetailViewBuilder, DetailViewConfig, DetailViewDefinition, DetailViewLayout, DocumentAttribute, DocumentSlotConfig, DocumentSlotValidationError, DocumentsTabConfig, type DomainEvent, DuplicateError, EMPTY_VALUE_PLACEHOLDER, type EffectivePermissions, type EventDataMap, type EventType, type ExtractRecord, type ExtractRecordInput, type ExtractRecordInputStrict, type ExtractRecordStrict, type ExtractRecordUpdate, type ExtractRecordUpdateStrict, FORM_FORBIDDEN_ATTRIBUTE_TYPES, FeatureFlagDefinition, FeatureFlagsRepository, FeatureGate, Field, FieldGroup, type File, FileAttribute, type FileListOptions, type FileVisibility, FilterOperator, FilterState, FilterValue, FlagLevel, FlagRegistry, FlagService, FlagValueType, ForbiddenError, FormBuilder, type FormDefinition, type FormFieldRef, type FormFieldsRow, type FormFreeFieldRef, type FormHeadingRow, FormRegistry, type FormRow, FormRowBuilder, type FormSeparatorRow, type FormSlot, type FormSlotFieldRef, type FormStatus, type FormStep, FormStepBuilder, type FormSubmission, type FormSubmissionStatus, type FormSubmittedAgentEvent, type FormTextRow, FormulaAttribute, type FormulaResult, FormulaReturnType, type GeocodingAdapter, type GeocodingAutocompleteParams, type GeocodingParams, type GeocodingSuggestion, type GlobalSearchGroupedOptions, type GlobalSearchGroupedResult, type GlobalSearchOptions, type GlobalSearchResultItem, type GrantResourceAccessInput, Group, GroupBuilder, IDENTITY_PROPERTIES, type InferAttributeValue, type InferQualifiedProps, InvalidPathError, type InviteUserInput, type ListOptions, ListViewBuilder, ListViewConfig, ListViewDefinition, ListViewTab, ListViewTabConfigBuilder, Location, LocationAttribute, LocationGranularity, MaxDepthExceededError, MemoryNotFoundError, type MentionEntityType, type MentionReference, type MentionedContext, type MentionedEntityContext, MigrationDefinition, type ModelDefinition, MultiRelationAttribute, MultiselectAttribute, NoopGeocodingAdapter, NotFoundError, NotImplementedError, NumberAttribute, OPERATOR_SPECS, ObjectBuilder, ObjectDefinition, ObjectNotFoundError, type ObjectPermissions, ObjectRecord, ObjectReferencedError, type OcrAdapter, type OcrInput, type OcrOptions, type OcrPage, type OcrResult, type OcrTextBlock, type OperatorSpec, Option, PRESENTATION_PROPERTIES, type PageInfo, type PageOptions, type PageResponse, type PathCardinality, type PathSegment, type PathSegmentType, type Permission, type PermissionScope, Phone, PhoneAttribute, type PolicyContext, PolicyViolationError, type PrincipalType, PropertySchema, ProtectedResourceError, ProtectedRoleError, type ProviderName, type QualifiedDocumentBrand, type QuestionResponse, type QuestionStatus, RatingAttribute, type ReasoningPartData, type RecordAgentEvent, type RecordMetadata, RecordNotFoundError, type RecordPolicy, type RecordReference, RecordReferencedError, RelationAttribute, RelationGroup, RelationGroupBuilder, type RelationOption, type RelationOptionsResponse, RelationTarget, RepositoryError, type RepositoryOperation, ResolvedFlag, type ResourceAccess, type ResourceRef, type RetryPolicy, type ReverseGeocodingParams, RichtextAttribute, RichtextFeature, RichtextTabConfig, type Role, RoleNotFoundError, RollupAttribute, RollupFunction, STANDARD_SCHEMA_VENDOR, SYSTEM_ATTRIBUTES, SYSTEM_ATTRIBUTE_I18N_KEYS, SYSTEM_RESOURCES, SYSTEM_RESOURCE_LABELS, type SandboxExecution, type SandboxExecutionInput, type SandboxExecutionResult, type SandboxExecutionStatus, type SandboxMode, type SandboxTrigger, SchemaError, SchemaErrorCode, type SchemaResolver, type SearchOptions, SelectAttribute, SidePanelConfig, type SidebarExtraItem, SingleRelationAttribute, type SlotMode, SortRule, type SpecificAccessAction, type StandardSchemaIssue, type StandardSchemaResult, StaticFlagDefault, StatusAttribute, StorageError, type StorageOperation, type StorageProvider, type StreamEventCompactionEnd, type StreamEventCompactionFailed, type StreamEventCompactionStart, type StreamEventMessagePersisted, SyncError, type SystemAttribute, type SystemAttributeI18nKey, type SystemFields, type SystemPermissions, type SystemResource, Tab, TabBuilder, TableTab, TableTabConfig, TenantId, TextAreaAttribute, TextAttribute, type TextPartData, type ThinkingPartData, type TimeoutPolicy, Timestamps, type ToolPartData, type ToolPartState, type TriggerEventType, USER_STATUSES, type UpdateActorInput, type UpdateDBAttribute, type UpdateDBForm, type UpdateDBFormSubmission, type UpdateDBObject, type UpdateDBView, type UpdateDBViewOverlay, type UpdateFile, type UpdateObjectInput, type UpdateRoleInput, type UpdateUserProfile, type UpdateViewInput, type UpsertAccessPolicyInput, type UpsertDBAttribute, type UpsertDBObject, type UpsertDBView, UserAttribute, type UserProfile, type UserRoleAssignment, type UserStatus, Uuid, ValidationError, type ValidationErrorDetail, ViewConfig, ViewDefinition, ViewType, type WithCustomAttributes$1 as WithCustomAttributes, accessLevelToActions, actionsToAccessLevel, applyPipes, booleanFlag, buildPropertySchema, checkbox, createFlagRegistry, createFlagService, createStandardSchemaProps, currency, date, detailView, document, evaluateFilterState, evaluateFormula, evaluateFormulaAttribute, evaluateFormulaWithResult, extractAttributeNames, extractFormulaVariables, extractRelationNames, extractRelationReferences, file, flagRegistry, flattenRelationsForEval, form, formRegistry, formatAttributeValue, formatFormulaResult, formula, generateDefaultDetailView, generateDefaultListView, getActiveTab, getErrorMessage, getPathDepth, getRelationPath, getSystemAttributeI18nKey, getSystemAttributeList, getTargetAttributeName, group, hasRelationReferences, isAttributeInUseError, isDefaultRole, isDocumentAttribute, isEmptyObject, isFormDefinition, isFormFieldsRow, isFormFreeFieldRef, isFormHeadingRow, isFormSeparatorRow, isFormSlotFieldRef, isFormTextRow, isLabelExpression, isNotEmpty, isNotFoundError, isObjectReferencedError, isProtectedResourceError, isRecordReferencedError, isSchemaError, isStandardSchema, isValidationError, jsonFlag, listView, location, matchesMime, multiselect, normaliseDocumentSlots, number, numberFlag, object, parsePath, pathHasManyCardinality, phone, rating, registry, relation, relationGroup, renderLabelExpression, resetViewToDefault, richtext, rollup, select, status, stringFlag, text, textarea, toUndefinedIfEmpty, user, validateAttributeName, validateFormulaExpression, validatePath, validateSlotAgainstConfig, viewRegistry };
package/dist/index.js CHANGED
@@ -748,6 +748,33 @@ function validateSlotAgainstConfig(slotName, mimeType, slots) {
748
748
  }
749
749
  return slot;
750
750
  }
751
+
752
+ // src/lib/qualify-with.ts
753
+ var ALLOWED_PROPERTY_TYPES = Object.freeze([
754
+ "text",
755
+ "textarea",
756
+ "number",
757
+ "checkbox",
758
+ "date",
759
+ "phone",
760
+ "currency",
761
+ "status",
762
+ "select",
763
+ "multiselect",
764
+ "rating",
765
+ "location"
766
+ ]);
767
+ function buildPropertySchema(builders) {
768
+ const definitions = [];
769
+ for (const builder of builders) {
770
+ const attr = builder.build();
771
+ if (!ALLOWED_PROPERTY_TYPES.includes(attr.type)) {
772
+ throw new Error(`Property type "${attr.type}" is not supported in .qualifyWith()`);
773
+ }
774
+ definitions.push(attr);
775
+ }
776
+ return { definitions };
777
+ }
751
778
  var EMPTY_VALUE_PLACEHOLDER = "\u2014";
752
779
  function formatText(value) {
753
780
  return String(value);
@@ -1263,15 +1290,6 @@ function validateOptions(options, attributeName) {
1263
1290
  }
1264
1291
 
1265
1292
  // src/builders/attribute-builders.ts
1266
- var FORBIDDEN_PROPERTY_TYPES = [
1267
- "formula",
1268
- "rollup",
1269
- "relation",
1270
- "file",
1271
- "user",
1272
- "document",
1273
- "richtext"
1274
- ];
1275
1293
  function asMutableArray(arr) {
1276
1294
  return arr;
1277
1295
  }
@@ -1879,14 +1897,7 @@ var BaseRelationAttributeBuilder = class extends BaseAttributeBuilder {
1879
1897
  '.qualifyWith() must be called AFTER .to(). Example: relation({ name: "companies" }).to("companies").qualifyWith(...)'
1880
1898
  );
1881
1899
  }
1882
- const definitions = builders.map((builder) => {
1883
- const attr = builder.build();
1884
- if (FORBIDDEN_PROPERTY_TYPES.includes(attr.type)) {
1885
- throw new Error(`Property type "${attr.type}" is not supported in .qualifyWith()`);
1886
- }
1887
- return attr;
1888
- });
1889
- this.attr.properties = { definitions };
1900
+ this.attr.properties = buildPropertySchema(builders);
1890
1901
  return this;
1891
1902
  }
1892
1903
  /**
@@ -2140,7 +2151,7 @@ var DocumentAttributeBuilder = class extends BaseAttributeBuilder {
2140
2151
  }
2141
2152
  /**
2142
2153
  * Allow multiple documents.
2143
- * Value becomes string[] instead of string.
2154
+ * Value becomes string[] instead of string (or Array<{ id; props }> when qualified).
2144
2155
  */
2145
2156
  multiple() {
2146
2157
  this.attr.multiple = true;
@@ -2184,6 +2195,24 @@ var DocumentAttributeBuilder = class extends BaseAttributeBuilder {
2184
2195
  this.attr.attributes = [...this.attr.attributes, builder.build()];
2185
2196
  return this;
2186
2197
  }
2198
+ /**
2199
+ * Add properties to qualify each document using existing attribute builders.
2200
+ * Returns a new builder type that carries the inferred props shape for $infer.
2201
+ *
2202
+ * @example
2203
+ * document({ name: "contracts", label: "Contracts" })
2204
+ * .multiple()
2205
+ * .qualifyWith(
2206
+ * select({ name: "kind", label: "Kind" }).options([...]),
2207
+ * number({ name: "amount", label: "Amount" }).min(0),
2208
+ * )
2209
+ */
2210
+ qualifyWith(...builders) {
2211
+ this.attr.properties = buildPropertySchema(
2212
+ builders
2213
+ );
2214
+ return this;
2215
+ }
2187
2216
  /**
2188
2217
  * Mark this attribute as required.
2189
2218
  */
@@ -3006,6 +3035,35 @@ var RelationGroupBuilder = class {
3006
3035
  return this.data;
3007
3036
  }
3008
3037
  };
3038
+ function assertViewVersion(version) {
3039
+ if (version < 1) throw new Error("View version must be >= 1");
3040
+ }
3041
+ function assertUniqueBy(items, getKey, buildError) {
3042
+ const seen = /* @__PURE__ */ new Set();
3043
+ for (const item of items) {
3044
+ const key = getKey(item);
3045
+ if (seen.has(key)) {
3046
+ throw new Error(buildError(key));
3047
+ }
3048
+ seen.add(key);
3049
+ }
3050
+ }
3051
+ function validateViewName(name, builderName, examples) {
3052
+ const viewNameSchema = z3.z.string().min(1, "View name cannot be empty").max(63, "View name is too long (max 63 characters)").regex(/^[a-z][a-z0-9-]*$/, {
3053
+ message: `Invalid view name format.
3054
+ Name must be in kebab-case:
3055
+ \u2705 Valid: ${examples.valid}
3056
+ \u274C Invalid: ${examples.invalid}`
3057
+ });
3058
+ try {
3059
+ viewNameSchema.parse(name);
3060
+ } catch (error) {
3061
+ if (error instanceof z3.z.ZodError) {
3062
+ throw new Error(`[${builderName}] ${error.issues[0].message}`);
3063
+ }
3064
+ throw error;
3065
+ }
3066
+ }
3009
3067
  var TableTabConfig = class {
3010
3068
  /** @internal */
3011
3069
  constructor(view, tabData) {
@@ -3416,7 +3474,10 @@ var TabBuilder = class {
3416
3474
  var DetailViewBuilder = class {
3417
3475
  constructor(name, label) {
3418
3476
  this._version = 1;
3419
- this.validateName(name);
3477
+ validateViewName(name, "DetailViewBuilder", {
3478
+ valid: "'detail', 'list-view', 'company-detail'",
3479
+ invalid: "'Detail', 'listView', 'list_view'"
3480
+ });
3420
3481
  this.data = {
3421
3482
  name,
3422
3483
  label,
@@ -3484,7 +3545,7 @@ var DetailViewBuilder = class {
3484
3545
  * @default 1
3485
3546
  */
3486
3547
  version(v) {
3487
- if (v < 1) throw new Error("View version must be >= 1");
3548
+ assertViewVersion(v);
3488
3549
  this._version = v;
3489
3550
  return this;
3490
3551
  }
@@ -3528,13 +3589,11 @@ var DetailViewBuilder = class {
3528
3589
  if (this.data.tabs.length === 0) {
3529
3590
  throw new Error("[DetailViewBuilder] At least one tab is required");
3530
3591
  }
3531
- const tabNames = /* @__PURE__ */ new Set();
3532
- for (const tab of this.data.tabs) {
3533
- if (tabNames.has(tab.name)) {
3534
- throw new Error(`[DetailViewBuilder] Duplicate tab name "${tab.name}"`);
3535
- }
3536
- tabNames.add(tab.name);
3537
- }
3592
+ assertUniqueBy(
3593
+ this.data.tabs,
3594
+ (tab) => tab.name,
3595
+ (name) => `[DetailViewBuilder] Duplicate tab name "${name}"`
3596
+ );
3538
3597
  if (this.data.layout === "modal") {
3539
3598
  if (this.data.tabs.length !== 1) {
3540
3599
  throw new Error("[DetailViewBuilder] Modal views must have exactly one tab");
@@ -3564,22 +3623,6 @@ var DetailViewBuilder = class {
3564
3623
  schema_version: this._version
3565
3624
  };
3566
3625
  }
3567
- /**
3568
- * Validate view name format (kebab-case)
3569
- */
3570
- validateName(name) {
3571
- const viewNameSchema = z3.z.string().min(1, "View name cannot be empty").max(63, "View name is too long (max 63 characters)").regex(/^[a-z][a-z0-9-]*$/, {
3572
- message: "Invalid view name format.\nName must be in kebab-case:\n \u2705 Valid: 'detail', 'list-view', 'company-detail'\n \u274C Invalid: 'Detail', 'listView', 'list_view'"
3573
- });
3574
- try {
3575
- viewNameSchema.parse(name);
3576
- } catch (error) {
3577
- if (error instanceof z3.z.ZodError) {
3578
- throw new Error(`[DetailViewBuilder] ${error.issues[0].message}`);
3579
- }
3580
- throw error;
3581
- }
3582
- }
3583
3626
  };
3584
3627
  function detailView(name, label) {
3585
3628
  return new DetailViewBuilder(name, label);
@@ -3587,7 +3630,10 @@ function detailView(name, label) {
3587
3630
  var ListViewBuilder = class {
3588
3631
  constructor(name, label) {
3589
3632
  this._version = 1;
3590
- this.validateName(name);
3633
+ validateViewName(name, "ListViewBuilder", {
3634
+ valid: "'default', 'list-view', 'active-contacts'",
3635
+ invalid: "'Default', 'listView', 'list_view'"
3636
+ });
3591
3637
  this.data = {
3592
3638
  name,
3593
3639
  label,
@@ -3637,7 +3683,7 @@ var ListViewBuilder = class {
3637
3683
  * @default 1
3638
3684
  */
3639
3685
  version(v) {
3640
- if (v < 1) throw new Error("View version must be >= 1");
3686
+ assertViewVersion(v);
3641
3687
  this._version = v;
3642
3688
  return this;
3643
3689
  }
@@ -3679,13 +3725,11 @@ var ListViewBuilder = class {
3679
3725
  if (this.data.tabs.length === 0) {
3680
3726
  throw new Error("[ListViewBuilder] At least one tab is required");
3681
3727
  }
3682
- const tabIds = /* @__PURE__ */ new Set();
3683
- for (const tab of this.data.tabs) {
3684
- if (tabIds.has(tab.id)) {
3685
- throw new Error(`[ListViewBuilder] Duplicate tab id "${tab.id}"`);
3686
- }
3687
- tabIds.add(tab.id);
3688
- }
3728
+ assertUniqueBy(
3729
+ this.data.tabs,
3730
+ (tab) => tab.id,
3731
+ (id) => `[ListViewBuilder] Duplicate tab id "${id}"`
3732
+ );
3689
3733
  const defaultTabs = this.data.tabs.filter((t) => t.default);
3690
3734
  if (defaultTabs.length > 1) {
3691
3735
  throw new Error("[ListViewBuilder] Only one tab can be marked as default");
@@ -3740,22 +3784,6 @@ var ListViewBuilder = class {
3740
3784
  schema_version: this._version
3741
3785
  };
3742
3786
  }
3743
- /**
3744
- * Validate view name format (kebab-case)
3745
- */
3746
- validateName(name) {
3747
- const viewNameSchema = z3.z.string().min(1, "View name cannot be empty").max(63, "View name is too long (max 63 characters)").regex(/^[a-z][a-z0-9-]*$/, {
3748
- message: "Invalid view name format.\nName must be in kebab-case:\n \u2705 Valid: 'default', 'list-view', 'active-contacts'\n \u274C Invalid: 'Default', 'listView', 'list_view'"
3749
- });
3750
- try {
3751
- viewNameSchema.parse(name);
3752
- } catch (error) {
3753
- if (error instanceof z3.z.ZodError) {
3754
- throw new Error(`[ListViewBuilder] ${error.issues[0].message}`);
3755
- }
3756
- throw error;
3757
- }
3758
- }
3759
3787
  };
3760
3788
  var ListViewTabConfigBuilder = class _ListViewTabConfigBuilder {
3761
3789
  /** @internal */
@@ -5575,6 +5603,10 @@ Object.defineProperty(exports, "createFormAttributeValidator", {
5575
5603
  enumerable: true,
5576
5604
  get: function () { return chunk64R5X3DF_js.createFormAttributeValidator; }
5577
5605
  });
5606
+ Object.defineProperty(exports, "validateDraft", {
5607
+ enumerable: true,
5608
+ get: function () { return chunk64R5X3DF_js.validateDraft; }
5609
+ });
5578
5610
  Object.defineProperty(exports, "validateDraftOrThrow", {
5579
5611
  enumerable: true,
5580
5612
  get: function () { return chunk64R5X3DF_js.validateDraftOrThrow; }
@@ -5595,6 +5627,7 @@ Object.defineProperty(exports, "formatZodErrors", {
5595
5627
  enumerable: true,
5596
5628
  get: function () { return chunkT225DB55_js.formatZodErrors; }
5597
5629
  });
5630
+ exports.ALLOWED_PROPERTY_TYPES = ALLOWED_PROPERTY_TYPES;
5598
5631
  exports.ALL_ACTIONS = ALL_ACTIONS;
5599
5632
  exports.ALL_SYSTEM_RESOURCES = ALL_SYSTEM_RESOURCES;
5600
5633
  exports.AccessDeniedError = AccessDeniedError;
@@ -5670,6 +5703,7 @@ exports.accessLevelToActions = accessLevelToActions;
5670
5703
  exports.actionsToAccessLevel = actionsToAccessLevel;
5671
5704
  exports.applyPipes = applyPipes;
5672
5705
  exports.booleanFlag = booleanFlag;
5706
+ exports.buildPropertySchema = buildPropertySchema;
5673
5707
  exports.checkbox = checkbox;
5674
5708
  exports.createFlagRegistry = createFlagRegistry;
5675
5709
  exports.createFlagService = createFlagService;