@stndrds/schema 0.1.0-alpha.56 → 0.1.0-alpha.58

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/dist/index.mjs CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  AttributeNotFoundError,
5
5
  AuditService,
6
6
  AuthMethodSchema,
7
+ BEHAVIOR_PROPERTIES,
7
8
  BaseRepository,
8
9
  BaseService,
9
10
  ConcurrentModificationError,
@@ -16,8 +17,8 @@ import {
16
17
  CustomTabConfig,
17
18
  DEFAULT_LABEL_FALLBACK,
18
19
  DEFAULT_THEME,
19
- DEFAULT_VALIDATION_MESSAGES,
20
20
  DRIVING_LICENSE,
21
+ DetailViewBuilder,
21
22
  DirectTableTabConfig,
22
23
  DocumentExecutor,
23
24
  DocumentGenerationNotConfiguredError,
@@ -37,6 +38,7 @@ import {
37
38
  EndNodeSchema,
38
39
  ExecutorRegistry,
39
40
  FRENCH_ID_CARD,
41
+ FeatureFlagsContextError,
40
42
  FileNotFoundError,
41
43
  FileService,
42
44
  FlowRowFieldSchema,
@@ -54,12 +56,15 @@ import {
54
56
  GrantNotFoundError,
55
57
  GrantRevokedError,
56
58
  GroupBuilder,
59
+ IDENTITY_PROPERTIES,
57
60
  InvalidPathError,
58
61
  InverseTableTabConfig,
59
62
  InvitationAlreadyAcceptedError,
60
63
  InvitationExpiredError,
61
64
  InvitationNotFoundError,
62
65
  InvitationRevokedError,
66
+ ListViewBuilder,
67
+ ListViewTabConfigBuilder,
63
68
  MaxDepthExceededError,
64
69
  NodePositionSchema,
65
70
  NoopCacheAdapter,
@@ -73,6 +78,7 @@ import {
73
78
  ObjectReferencedError,
74
79
  ObjectSchemaService,
75
80
  PASSPORT,
81
+ PRESENTATION_PROPERTIES,
76
82
  PROOF_OF_ADDRESS,
77
83
  PermissionService,
78
84
  PolicyRegistry,
@@ -144,9 +150,6 @@ import {
144
150
  addSchemaToContext,
145
151
  and,
146
152
  applyDefaultValues,
147
- asTenantId,
148
- asUserId,
149
- attributeConfigSchemas,
150
153
  buildAuditChanges,
151
154
  buildPolicyContext,
152
155
  cacheKeys,
@@ -159,53 +162,25 @@ import {
159
162
  checkRecordModifyOrThrow,
160
163
  checkSharedObjectWriteAccess,
161
164
  checkbox,
162
- checkboxConfigSchema,
163
165
  complete,
164
166
  computeLabel,
165
167
  computeLabelWithRelations,
166
- computeRecordStatus,
167
- createAttributeValidator,
168
- createCheckboxValidator,
169
168
  createContextForCreate,
170
169
  createContextForDelete,
171
170
  createContextForRestore,
172
171
  createContextForUpdate,
173
- createCurrencyValidator,
174
- createDateValidator,
175
172
  createDefaultExecutorRegistry,
176
173
  createDefaultState,
177
- createDraftValidator,
178
174
  createEmptyContext,
179
- createFileValidator,
180
- createFormAttributeValidator,
181
- createFormulaValidator,
182
- createLocationValidator,
183
175
  createMockAdapter,
184
- createMultiRelationValidator,
185
- createMultiselectValidator,
186
- createNumberValidator,
187
- createObjectValidator,
188
- createPhoneValidator,
189
176
  createQueryBuilder,
190
- createRatingValidator,
191
- createRelationValidator,
192
- createRichtextValidator,
193
- createRollupValidator,
194
- createSelectValidator,
195
- createSingleRelationValidator,
196
177
  createStartTransition,
197
- createStatusValidator,
198
- createTextAreaValidator,
199
- createTextValidator,
200
- createUserValidator,
201
178
  currency,
202
- currencyConfigSchema,
203
179
  date,
204
- dateConfigSchema,
205
180
  defaultPolicyRegistry,
206
181
  defaultTtl,
182
+ detailView,
207
183
  document,
208
- documentConfigSchema,
209
184
  enrichRecordsWithFormulas,
210
185
  enrichValuesForDisplay,
211
186
  enrichValuesWithSelectLabels,
@@ -226,23 +201,18 @@ import {
226
201
  extractRelationNames,
227
202
  extractRelationReferences,
228
203
  file,
229
- fileConfigSchema,
230
204
  flattenRelationsForEval,
231
205
  formatAttributeValue,
232
206
  formatFormulaResult,
233
207
  formatRecord,
234
208
  formatRecords,
235
209
  formula,
236
- formulaConfigSchema,
237
210
  generateCssVariables,
238
- generateId,
239
- generatePrefixedId,
240
- generateTemplateName,
241
- getAttributeConfigSchema,
242
211
  getContext,
243
212
  getContextValue,
244
213
  getDefaultExecutorRegistry,
245
- getMissingRequiredAttributes,
214
+ getFeatureFlags,
215
+ getFeatureValue,
246
216
  getNodeOutputs,
247
217
  getPathDepth,
248
218
  getPolicy,
@@ -256,26 +226,31 @@ import {
256
226
  getTargetAttributeName,
257
227
  getTenantId,
258
228
  getUserId,
229
+ getViewSeedPreview,
259
230
  getViewSyncPreview,
260
231
  group,
261
232
  hasContext,
233
+ hasFeatureFlagsContext,
234
+ hasProperties,
262
235
  hasRelationReferences,
263
236
  hasSchemaContext,
264
237
  hashOptions,
265
238
  inValues,
266
239
  isAdvancedFormNode,
267
- isConcurrentModificationError,
240
+ isBehaviorProperty,
268
241
  isConditionGroup,
269
242
  isConditionNode,
270
243
  isConditionRule,
271
244
  isDocumentNode,
272
245
  isEmpty,
273
246
  isEndNode,
247
+ isFeatureEnabled,
274
248
  isForbiddenError,
275
249
  isFormNode,
276
250
  isGrantExpired,
277
251
  isGrantRevoked,
278
252
  isGrantValid,
253
+ isIdentityProperty,
279
254
  isInstanceEvent,
280
255
  isInstanceTerminal,
281
256
  isInstanceWaiting,
@@ -287,8 +262,8 @@ import {
287
262
  isNodeEvent,
288
263
  isNotEmpty,
289
264
  isNotFoundError,
265
+ isPresentationProperty,
290
266
  isProtectedResourceError,
291
- isRecordComplete,
292
267
  isSchemaError,
293
268
  isSimpleFormNode,
294
269
  isStartNode,
@@ -301,72 +276,125 @@ import {
301
276
  isValidationError,
302
277
  isWorkflowDefinition,
303
278
  isWorkflowPublished,
279
+ listView,
304
280
  location,
305
- locationConfigSchema,
306
- mergeFormToSlot,
307
281
  mergeWithDefaults,
308
282
  multiselect,
309
- multiselectConfigSchema,
310
283
  neq,
311
284
  notesPolicy,
312
285
  number,
313
- numberConfigSchema,
314
286
  object,
315
287
  or,
316
- parseAttributeConfig,
317
288
  parsePath,
318
289
  pathHasManyCardinality,
319
290
  phone,
320
- phoneConfigSchema,
321
291
  rating,
322
- ratingConfigSchema,
323
292
  recalculateParentRollups,
324
293
  registry,
325
294
  relation,
326
- relationConfigSchema,
327
295
  renderLabelExpression,
328
296
  resolveMultiplePaths,
329
297
  resolveSingleValue,
330
298
  richtext,
331
- richtextConfigSchema,
332
299
  rollup,
333
- rollupConfigSchema,
334
300
  runWithContext,
301
+ runWithFeatureFlags,
335
302
  runWithMergedSchemaContext,
336
303
  runWithSchemaContext,
337
- safeParseAttributeConfig,
304
+ seedRegistryViews,
338
305
  select,
339
- selectConfigSchema,
340
306
  setContextValue,
341
- slugify,
342
307
  status,
343
- statusConfigSchema,
344
308
  success,
345
309
  syncAll,
346
310
  syncNativeObjects,
347
311
  syncNativeViews,
348
312
  text,
349
- textConfigSchema,
350
313
  textarea,
351
- textareaConfigSchema,
314
+ toUndefinedIfEmpty,
352
315
  traversePath,
316
+ tryGetFeatureValue,
353
317
  user,
354
- userConfigSchema,
355
- validateAttribute,
356
- validateAttributeConfig,
357
- validateDraft,
358
- validateDraftOrThrow,
359
318
  validateFormulaExpression,
360
- validateObject,
361
- validateObjectOrThrow,
362
319
  validatePath,
363
320
  verifyNativeObjectsSync,
364
321
  verifyNativeViewsSync,
322
+ verifyRegistryViewsSeeded,
365
323
  view,
366
324
  wait,
325
+ withFeatureFlags,
367
326
  withTenantContext,
368
327
  workflow
369
- } from "./chunk-LOOGQL6M.mjs";
328
+ } from "./chunk-JRY236AO.mjs";
329
+ import {
330
+ asTenantId,
331
+ asUserId,
332
+ generateId,
333
+ generatePrefixedId,
334
+ generateTemplateName,
335
+ indexBy,
336
+ slugify
337
+ } from "./chunk-V2RPPE2Y.mjs";
338
+ import {
339
+ DEFAULT_VALIDATION_MESSAGES,
340
+ attributeConfigSchemas,
341
+ checkboxConfigSchema,
342
+ computeRecordStatus,
343
+ createAttributeValidator,
344
+ createCheckboxValidator,
345
+ createCurrencyValidator,
346
+ createDateValidator,
347
+ createDraftValidator,
348
+ createFileValidator,
349
+ createFormAttributeValidator,
350
+ createFormulaValidator,
351
+ createLocationValidator,
352
+ createMultiRelationValidator,
353
+ createMultiselectValidator,
354
+ createNumberValidator,
355
+ createObjectValidator,
356
+ createPhoneValidator,
357
+ createRatingValidator,
358
+ createRelationValidator,
359
+ createRichtextValidator,
360
+ createRollupValidator,
361
+ createSelectValidator,
362
+ createSingleRelationValidator,
363
+ createStatusValidator,
364
+ createTextAreaValidator,
365
+ createTextValidator,
366
+ createUserValidator,
367
+ currencyConfigSchema,
368
+ dateConfigSchema,
369
+ documentConfigSchema,
370
+ fileConfigSchema,
371
+ formatZodErrors,
372
+ formulaConfigSchema,
373
+ getAttributeConfigSchema,
374
+ getMissingRequiredAttributes,
375
+ isRecordComplete,
376
+ locationConfigSchema,
377
+ multiselectConfigSchema,
378
+ numberConfigSchema,
379
+ parseAttributeConfig,
380
+ phoneConfigSchema,
381
+ ratingConfigSchema,
382
+ relationConfigSchema,
383
+ richtextConfigSchema,
384
+ rollupConfigSchema,
385
+ safeParseAttributeConfig,
386
+ selectConfigSchema,
387
+ statusConfigSchema,
388
+ textConfigSchema,
389
+ textareaConfigSchema,
390
+ userConfigSchema,
391
+ validateAttribute,
392
+ validateAttributeConfig,
393
+ validateDraft,
394
+ validateDraftOrThrow,
395
+ validateObject,
396
+ validateObjectOrThrow
397
+ } from "./chunk-SV4BCGQU.mjs";
370
398
  import {
371
399
  ALL_SYSTEM_RESOURCES,
372
400
  DEFAULT_ROLES,
@@ -379,43 +407,7 @@ import {
379
407
  } from "./chunk-V5QXU2OK.mjs";
380
408
  import "./chunk-Y6FXYEAI.mjs";
381
409
 
382
- // src/types/document-generation.ts
383
- function isPdfTemplateSource(source) {
384
- return source.type === "pdf";
385
- }
386
- function isDocxTemplateSource(source) {
387
- return source.type === "docx";
388
- }
389
-
390
410
  // src/types/filters.ts
391
- function isAdvancedFilterState(state) {
392
- return "groups" in state;
393
- }
394
- function toAdvancedFilterState(state) {
395
- if (state.rules.length === 0) {
396
- return {
397
- combinator: state.combinator,
398
- groups: []
399
- };
400
- }
401
- return {
402
- combinator: "and",
403
- groups: [
404
- {
405
- id: crypto.randomUUID(),
406
- combinator: state.combinator,
407
- rules: state.rules
408
- }
409
- ]
410
- };
411
- }
412
- function toSimpleFilterState(state) {
413
- const allRules = state.groups.flatMap((group2) => group2.rules);
414
- return {
415
- combinator: state.combinator,
416
- rules: allRules
417
- };
418
- }
419
411
  var OPERATORS_BY_TYPE = {
420
412
  text: [
421
413
  "is",
@@ -503,6 +495,21 @@ function isSystemFlow(flow) {
503
495
  }
504
496
 
505
497
  // src/types/views.ts
498
+ function isDetailView(view2) {
499
+ return view2.type === "detail";
500
+ }
501
+ function isListView(view2) {
502
+ return view2.type === "list";
503
+ }
504
+ function isCalendarView(view2) {
505
+ return view2.type === "calendar";
506
+ }
507
+ function isTimelineView(view2) {
508
+ return view2.type === "timeline";
509
+ }
510
+ function isGalleryView(view2) {
511
+ return view2.type === "gallery";
512
+ }
506
513
  function isFormTab(tab) {
507
514
  return tab.type === "form";
508
515
  }
@@ -531,6 +538,523 @@ function isDocumentsTab(tab) {
531
538
  return tab.type === "documents";
532
539
  }
533
540
 
541
+ // src/feature-flags/flag-builder.ts
542
+ function validateFlagName(name) {
543
+ if (!/^[a-z][a-z0-9-]*[a-z0-9]$|^[a-z]$/.test(name)) {
544
+ throw new Error(
545
+ `Invalid flag name "${name}". Flag names must be kebab-case (e.g., "architect-mode", "ai-features").`
546
+ );
547
+ }
548
+ }
549
+ var BaseFlagBuilder = class {
550
+ constructor(name, valueType, defaultValue) {
551
+ validateFlagName(name);
552
+ this.flag = {
553
+ name,
554
+ valueType,
555
+ defaultValue,
556
+ allowedLevels: ["global", "tenant", "user"]
557
+ };
558
+ }
559
+ /**
560
+ * Set the human-readable label for the flag.
561
+ * Required - build() will throw if not set.
562
+ */
563
+ label(value) {
564
+ this.flag.label = value;
565
+ return this;
566
+ }
567
+ /**
568
+ * Set an optional description for the flag.
569
+ */
570
+ description(value) {
571
+ this.flag.description = value;
572
+ return this;
573
+ }
574
+ /**
575
+ * Set a category for grouping flags in UI.
576
+ */
577
+ category(value) {
578
+ this.flag.category = value;
579
+ return this;
580
+ }
581
+ /**
582
+ * Mark this flag as a system flag.
583
+ * System flags cannot be modified via API.
584
+ */
585
+ system() {
586
+ this.flag.system = true;
587
+ return this;
588
+ }
589
+ /**
590
+ * Restrict the flag to global and tenant levels only.
591
+ * Per-user overrides will not be allowed.
592
+ */
593
+ tenantScoped() {
594
+ this.flag.allowedLevels = ["global", "tenant"];
595
+ return this;
596
+ }
597
+ /**
598
+ * Restrict the flag to global level only.
599
+ * No tenant or user overrides will be allowed.
600
+ */
601
+ globalOnly() {
602
+ this.flag.allowedLevels = ["global"];
603
+ return this;
604
+ }
605
+ /**
606
+ * Set custom allowed levels.
607
+ */
608
+ allowedLevels(levels) {
609
+ this.flag.allowedLevels = levels;
610
+ return this;
611
+ }
612
+ /**
613
+ * Build the flag definition.
614
+ * @throws {Error} If label is not set
615
+ */
616
+ build() {
617
+ if (!this.flag.label) {
618
+ throw new Error(
619
+ `Flag "${this.flag.name}" must have a label. Use .label("Human-readable label").`
620
+ );
621
+ }
622
+ return this.flag;
623
+ }
624
+ };
625
+ var BooleanFlagBuilder = class extends BaseFlagBuilder {
626
+ constructor(name) {
627
+ super(name, "boolean", false);
628
+ }
629
+ /**
630
+ * Set the default value (default: false).
631
+ */
632
+ defaultValue(value) {
633
+ this.flag.defaultValue = value;
634
+ return this;
635
+ }
636
+ /**
637
+ * Set the default to true.
638
+ * Shorthand for .defaultValue(true).
639
+ */
640
+ enabledByDefault() {
641
+ this.flag.defaultValue = true;
642
+ return this;
643
+ }
644
+ };
645
+ var StringFlagBuilder = class extends BaseFlagBuilder {
646
+ constructor(name) {
647
+ super(name, "string", "");
648
+ }
649
+ /**
650
+ * Set the default value.
651
+ */
652
+ defaultValue(value) {
653
+ this.flag.defaultValue = value;
654
+ return this;
655
+ }
656
+ };
657
+ var NumberFlagBuilder = class extends BaseFlagBuilder {
658
+ constructor(name) {
659
+ super(name, "number", 0);
660
+ }
661
+ /**
662
+ * Set the default value.
663
+ */
664
+ defaultValue(value) {
665
+ this.flag.defaultValue = value;
666
+ return this;
667
+ }
668
+ };
669
+ var JsonFlagBuilder = class extends BaseFlagBuilder {
670
+ constructor(name, defaultValue) {
671
+ super(name, "json", defaultValue);
672
+ }
673
+ /**
674
+ * Set the default value.
675
+ */
676
+ defaultValue(value) {
677
+ this.flag.defaultValue = value;
678
+ return this;
679
+ }
680
+ };
681
+ function booleanFlag(name) {
682
+ return new BooleanFlagBuilder(name);
683
+ }
684
+ function stringFlag(name) {
685
+ return new StringFlagBuilder(name);
686
+ }
687
+ function numberFlag(name) {
688
+ return new NumberFlagBuilder(name);
689
+ }
690
+ function jsonFlag(name, defaultValue) {
691
+ return new JsonFlagBuilder(name, defaultValue);
692
+ }
693
+
694
+ // src/feature-flags/flag-registry.ts
695
+ var FlagRegistry = class {
696
+ constructor() {
697
+ this.flags = /* @__PURE__ */ new Map();
698
+ }
699
+ /**
700
+ * Register a feature flag definition.
701
+ *
702
+ * @param flag - The flag definition to register
703
+ * @throws {Error} If a flag with the same name is already registered
704
+ *
705
+ * @example
706
+ * ```typescript
707
+ * registry.register(booleanFlag("my-feature")
708
+ * .label("My Feature")
709
+ * .build()
710
+ * );
711
+ * ```
712
+ */
713
+ register(flag) {
714
+ if (this.flags.has(flag.name)) {
715
+ throw new Error(`Flag "${flag.name}" is already registered. Each flag name must be unique.`);
716
+ }
717
+ this.flags.set(flag.name, flag);
718
+ }
719
+ /**
720
+ * Register multiple flags at once.
721
+ *
722
+ * @param flags - Array of flag definitions to register
723
+ */
724
+ registerAll(flags) {
725
+ for (const flag of flags) {
726
+ this.register(flag);
727
+ }
728
+ }
729
+ /**
730
+ * Get a flag definition by name.
731
+ *
732
+ * @param name - The flag name
733
+ * @returns The flag definition or undefined if not found
734
+ */
735
+ get(name) {
736
+ return this.flags.get(name);
737
+ }
738
+ /**
739
+ * Get a flag definition by name, throwing if not found.
740
+ *
741
+ * @param name - The flag name
742
+ * @returns The flag definition
743
+ * @throws {Error} If the flag is not registered
744
+ */
745
+ getOrThrow(name) {
746
+ const flag = this.get(name);
747
+ if (!flag) {
748
+ throw new Error(
749
+ `Flag "${name}" is not registered. Available flags: ${this.listNames().join(", ")}`
750
+ );
751
+ }
752
+ return flag;
753
+ }
754
+ /**
755
+ * Check if a flag is registered.
756
+ *
757
+ * @param name - The flag name
758
+ * @returns true if the flag is registered
759
+ */
760
+ has(name) {
761
+ return this.flags.has(name);
762
+ }
763
+ /**
764
+ * List all registered flag definitions.
765
+ *
766
+ * @returns Array of all flag definitions
767
+ */
768
+ list() {
769
+ return Array.from(this.flags.values());
770
+ }
771
+ /**
772
+ * List all registered flag names.
773
+ *
774
+ * @returns Array of flag names
775
+ */
776
+ listNames() {
777
+ return Array.from(this.flags.keys());
778
+ }
779
+ /**
780
+ * List flags filtered by category.
781
+ *
782
+ * @param category - The category to filter by
783
+ * @returns Array of flag definitions in the category
784
+ */
785
+ listByCategory(category) {
786
+ return this.list().filter((flag) => flag.category === category);
787
+ }
788
+ /**
789
+ * Get all unique categories.
790
+ *
791
+ * @returns Array of unique category names
792
+ */
793
+ getCategories() {
794
+ const categories = /* @__PURE__ */ new Set();
795
+ for (const flag of this.flags.values()) {
796
+ if (flag.category) {
797
+ categories.add(flag.category);
798
+ }
799
+ }
800
+ return Array.from(categories);
801
+ }
802
+ /**
803
+ * Get the default value for a flag.
804
+ *
805
+ * @param name - The flag name
806
+ * @returns The default value or undefined if flag not found
807
+ */
808
+ getDefaultValue(name) {
809
+ return this.get(name)?.defaultValue;
810
+ }
811
+ /**
812
+ * Get a map of all flag names to their default values.
813
+ *
814
+ * @returns Map of flag names to default values
815
+ */
816
+ getDefaults() {
817
+ const defaults = /* @__PURE__ */ new Map();
818
+ for (const [name, flag] of this.flags) {
819
+ defaults.set(name, flag.defaultValue);
820
+ }
821
+ return defaults;
822
+ }
823
+ /**
824
+ * Unregister a flag (mainly for testing).
825
+ *
826
+ * @param name - The flag name to unregister
827
+ * @returns true if the flag was removed, false if it didn't exist
828
+ */
829
+ unregister(name) {
830
+ return this.flags.delete(name);
831
+ }
832
+ /**
833
+ * Clear all registered flags (mainly for testing).
834
+ */
835
+ clear() {
836
+ this.flags.clear();
837
+ }
838
+ /**
839
+ * Get the number of registered flags.
840
+ */
841
+ get size() {
842
+ return this.flags.size;
843
+ }
844
+ };
845
+ var flagRegistry = new FlagRegistry();
846
+ function createFlagRegistry() {
847
+ return new FlagRegistry();
848
+ }
849
+
850
+ // src/feature-flags/flag-service.ts
851
+ var FlagService = class {
852
+ constructor(options) {
853
+ this.repository = options.repository;
854
+ this.registry = options.registry;
855
+ this.staticDefaults = new Map(options.staticDefaults?.map((d) => [d.name, d.value]) ?? []);
856
+ }
857
+ /**
858
+ * Resolve all flags for the current context.
859
+ * Returns a Map suitable for runWithFeatureFlags().
860
+ *
861
+ * @param context - Resolution context with tenant/user IDs
862
+ * @returns Map of flag names to resolved values
863
+ */
864
+ async resolveAll(context = {}) {
865
+ const resolved = /* @__PURE__ */ new Map();
866
+ const flagNames = /* @__PURE__ */ new Set();
867
+ for (const name of this.registry.listNames()) {
868
+ flagNames.add(name);
869
+ }
870
+ for (const name of this.staticDefaults.keys()) {
871
+ flagNames.add(name);
872
+ }
873
+ const overrides = this.repository ? await this.getAllOverrides(context) : { global: [], tenant: [], user: [] };
874
+ for (const name of flagNames) {
875
+ const value = this.resolveValue(name, overrides, context);
876
+ resolved.set(name, value);
877
+ }
878
+ return resolved;
879
+ }
880
+ /**
881
+ * Resolve a single flag with full metadata.
882
+ *
883
+ * @param flagName - The flag to resolve
884
+ * @param context - Resolution context
885
+ * @returns Resolved flag with source information
886
+ */
887
+ async resolve(flagName, context = {}) {
888
+ const overrides = this.repository ? await this.getAllOverrides(context) : { global: [], tenant: [], user: [] };
889
+ return this.resolveWithSource(flagName, overrides, context);
890
+ }
891
+ /**
892
+ * Quick check if a boolean flag is enabled.
893
+ *
894
+ * @param flagName - The flag to check
895
+ * @param context - Resolution context
896
+ * @returns true if the flag value is exactly true
897
+ */
898
+ async isEnabled(flagName, context = {}) {
899
+ const resolved = await this.resolve(flagName, context);
900
+ return resolved.value === true;
901
+ }
902
+ /**
903
+ * Get a flag value with type inference.
904
+ *
905
+ * @param flagName - The flag to get
906
+ * @param context - Resolution context
907
+ * @returns The resolved flag value
908
+ */
909
+ async getValue(flagName, context = {}) {
910
+ const resolved = await this.resolve(flagName, context);
911
+ return resolved.value;
912
+ }
913
+ /**
914
+ * Set an override for a flag.
915
+ *
916
+ * @param flagName - The flag to override
917
+ * @param level - The level of the override
918
+ * @param value - The override value
919
+ * @param options - Additional options
920
+ */
921
+ async setOverride(flagName, level, value, options = {}) {
922
+ if (!this.repository) {
923
+ throw new Error(
924
+ "Cannot set override: no FeatureFlagsRepository configured. Add featureFlags to your DatabaseAdapter to enable runtime overrides."
925
+ );
926
+ }
927
+ const flag = this.registry.get(flagName);
928
+ if (flag && !flag.allowedLevels.includes(level)) {
929
+ throw new Error(
930
+ `Flag "${flagName}" does not allow ${level}-level overrides. Allowed levels: ${flag.allowedLevels.join(", ")}`
931
+ );
932
+ }
933
+ if (flag?.system) {
934
+ throw new Error(`Flag "${flagName}" is a system flag and cannot be overridden via API.`);
935
+ }
936
+ await this.repository.setOverride({
937
+ flagName,
938
+ level,
939
+ value,
940
+ targetId: options.targetId,
941
+ expiresAt: options.expiresAt,
942
+ createdBy: options.createdBy
943
+ });
944
+ }
945
+ /**
946
+ * Delete an override.
947
+ *
948
+ * @param flagName - The flag name
949
+ * @param level - The level to delete
950
+ * @param targetId - Optional target ID for tenant/user level
951
+ */
952
+ async deleteOverride(flagName, level, targetId) {
953
+ if (!this.repository) {
954
+ throw new Error("Cannot delete override: no FeatureFlagsRepository configured.");
955
+ }
956
+ await this.repository.deleteOverride(flagName, level, targetId);
957
+ }
958
+ // ============================================================================
959
+ // PRIVATE HELPERS
960
+ // ============================================================================
961
+ /**
962
+ * Get all overrides organized by level.
963
+ */
964
+ async getAllOverrides(context) {
965
+ if (!this.repository) {
966
+ return { global: [], tenant: [], user: [] };
967
+ }
968
+ const [globalOverrides, tenantOverrides, userOverrides] = await Promise.all([
969
+ this.repository.getOverrides({ level: "global" }),
970
+ context.tenantId ? this.repository.getOverrides({ level: "tenant", targetId: context.tenantId }) : Promise.resolve([]),
971
+ context.userId ? this.repository.getOverrides({ level: "user", targetId: context.userId }) : Promise.resolve([])
972
+ ]);
973
+ return {
974
+ global: globalOverrides,
975
+ tenant: tenantOverrides,
976
+ user: userOverrides
977
+ };
978
+ }
979
+ /**
980
+ * Resolve a flag value from overrides and defaults.
981
+ */
982
+ resolveValue(flagName, overrides, context) {
983
+ const flag = this.registry.get(flagName);
984
+ const allowedLevels = flag?.allowedLevels ?? ["global", "tenant", "user"];
985
+ if (context.userId && allowedLevels.includes("user")) {
986
+ const userOverride = overrides.user.find((o) => o.flagName === flagName);
987
+ if (userOverride) return userOverride.value;
988
+ }
989
+ if (context.tenantId && allowedLevels.includes("tenant")) {
990
+ const tenantOverride = overrides.tenant.find((o) => o.flagName === flagName);
991
+ if (tenantOverride) return tenantOverride.value;
992
+ }
993
+ if (allowedLevels.includes("global")) {
994
+ const globalOverride = overrides.global.find((o) => o.flagName === flagName);
995
+ if (globalOverride) return globalOverride.value;
996
+ }
997
+ if (this.staticDefaults.has(flagName)) {
998
+ return this.staticDefaults.get(flagName);
999
+ }
1000
+ return flag?.defaultValue;
1001
+ }
1002
+ /**
1003
+ * Resolve a flag value with source information.
1004
+ */
1005
+ resolveWithSource(flagName, overrides, context) {
1006
+ const flag = this.registry.get(flagName);
1007
+ const allowedLevels = flag?.allowedLevels ?? ["global", "tenant", "user"];
1008
+ if (context.userId && allowedLevels.includes("user")) {
1009
+ const userOverride = overrides.user.find((o) => o.flagName === flagName);
1010
+ if (userOverride) {
1011
+ return {
1012
+ name: flagName,
1013
+ value: userOverride.value,
1014
+ source: "user",
1015
+ sourceId: context.userId
1016
+ };
1017
+ }
1018
+ }
1019
+ if (context.tenantId && allowedLevels.includes("tenant")) {
1020
+ const tenantOverride = overrides.tenant.find((o) => o.flagName === flagName);
1021
+ if (tenantOverride) {
1022
+ return {
1023
+ name: flagName,
1024
+ value: tenantOverride.value,
1025
+ source: "tenant",
1026
+ sourceId: context.tenantId
1027
+ };
1028
+ }
1029
+ }
1030
+ if (allowedLevels.includes("global")) {
1031
+ const globalOverride = overrides.global.find((o) => o.flagName === flagName);
1032
+ if (globalOverride) {
1033
+ return {
1034
+ name: flagName,
1035
+ value: globalOverride.value,
1036
+ source: "global"
1037
+ };
1038
+ }
1039
+ }
1040
+ if (this.staticDefaults.has(flagName)) {
1041
+ return {
1042
+ name: flagName,
1043
+ value: this.staticDefaults.get(flagName),
1044
+ source: "default"
1045
+ };
1046
+ }
1047
+ return {
1048
+ name: flagName,
1049
+ value: flag?.defaultValue ?? void 0,
1050
+ source: "default"
1051
+ };
1052
+ }
1053
+ };
1054
+ function createFlagService(options) {
1055
+ return new FlagService(options);
1056
+ }
1057
+
534
1058
  // src/native/notes.ts
535
1059
  var NOTES = object({ name: "notes", label: "Note" }).pluralLabel("Notes").icon("file-text").description("Notes that can be linked to any record or used globally").system().labelExpression("{{ title }}").attribute(text({ name: "title", label: "Title" }).placeholder("Untitled").required()).attribute(richtext({ name: "content", label: "Content" }).required()).attribute(
536
1060
  select({ name: "visibility", label: "Visibility" }).options([
@@ -545,12 +1069,12 @@ var ViewRegistry = class {
545
1069
  constructor() {
546
1070
  this.views = /* @__PURE__ */ new Map();
547
1071
  this.byObject = /* @__PURE__ */ new Map();
1072
+ this.byObjectAndType = /* @__PURE__ */ new Map();
548
1073
  }
549
1074
  /**
550
- * Register a native view
1075
+ * Register a view
551
1076
  * @param viewOrViews - Single view or array of views
552
- * @throws Error if view is not marked as system
553
- * @throws Error if view with same name already exists for the object
1077
+ * @throws Error if view with same name and type already exists for the object
554
1078
  */
555
1079
  register(viewOrViews) {
556
1080
  const views = Array.isArray(viewOrViews) ? viewOrViews : [viewOrViews];
@@ -560,22 +1084,20 @@ var ViewRegistry = class {
560
1084
  return this;
561
1085
  }
562
1086
  registerSingle(view2) {
563
- if (!view2.system) {
564
- throw new Error(
565
- `[ViewRegistry] View "${view2.name}" for object "${view2.object}" is missing system flag.
566
- Only system views can be registered. Add .system() to your view builder.`
567
- );
568
- }
569
- const key = this.makeKey(view2.object, view2.name);
1087
+ const key = this.makeKey(view2.object, view2.name, view2.type);
570
1088
  if (this.views.has(key)) {
571
1089
  throw new Error(
572
- `[ViewRegistry] Duplicate view name "${view2.name}" for object "${view2.object}"`
1090
+ `[ViewRegistry] Duplicate view: "${view2.name}" (${view2.type}) for object "${view2.object}"`
573
1091
  );
574
1092
  }
575
1093
  this.views.set(key, view2);
576
1094
  const objectViews = this.byObject.get(view2.object) ?? [];
577
1095
  objectViews.push(view2);
578
1096
  this.byObject.set(view2.object, objectViews);
1097
+ const typeKey = `${view2.object}:${view2.type}`;
1098
+ const typeViews = this.byObjectAndType.get(typeKey) ?? [];
1099
+ typeViews.push(view2);
1100
+ this.byObjectAndType.set(typeKey, typeViews);
579
1101
  }
580
1102
  /**
581
1103
  * Get all views for an object
@@ -584,19 +1106,29 @@ Only system views can be registered. Add .system() to your view builder.`
584
1106
  return this.byObject.get(objectName) ?? [];
585
1107
  }
586
1108
  /**
587
- * Get a specific view by object and view name
1109
+ * Get views for an object filtered by type
588
1110
  */
589
- get(objectName, viewName) {
590
- return this.views.get(this.makeKey(objectName, viewName));
1111
+ getByObjectNameAndType(objectName, type) {
1112
+ return this.byObjectAndType.get(`${objectName}:${type}`) ?? [];
1113
+ }
1114
+ /**
1115
+ * Get a specific view by object, name, and type
1116
+ */
1117
+ get(objectName, viewName, type) {
1118
+ if (type) {
1119
+ return this.views.get(this.makeKey(objectName, viewName, type));
1120
+ }
1121
+ const objectViews = this.getByObjectName(objectName);
1122
+ return objectViews.find((v) => v.name === viewName);
591
1123
  }
592
1124
  /**
593
1125
  * Get a view or throw if not found
594
1126
  */
595
- getOrThrow(objectName, viewName) {
596
- const view2 = this.get(objectName, viewName);
1127
+ getOrThrow(objectName, viewName, type) {
1128
+ const view2 = this.get(objectName, viewName, type);
597
1129
  if (!view2) {
598
1130
  const available = this.getByObjectName(objectName);
599
- const availableNames = available.map((v) => v.name).join(", ") || "(none)";
1131
+ const availableNames = available.map((v) => `${v.name} (${v.type})`).join(", ") || "(none)";
600
1132
  throw new Error(
601
1133
  `[ViewRegistry] View "${viewName}" not found for object "${objectName}".
602
1134
  Available views: ${availableNames}`
@@ -613,8 +1145,12 @@ Available views: ${availableNames}`
613
1145
  /**
614
1146
  * Check if a view exists
615
1147
  */
616
- has(objectName, viewName) {
617
- return this.views.has(this.makeKey(objectName, viewName));
1148
+ has(objectName, viewName, type) {
1149
+ if (type) {
1150
+ return this.views.has(this.makeKey(objectName, viewName, type));
1151
+ }
1152
+ const objectViews = this.getByObjectName(objectName);
1153
+ return objectViews.some((v) => v.name === viewName);
618
1154
  }
619
1155
  /**
620
1156
  * Check if any views exist for an object
@@ -635,10 +1171,10 @@ Available views: ${availableNames}`
635
1171
  return Array.from(this.byObject.keys());
636
1172
  }
637
1173
  /**
638
- * Get default view for an object (if any)
1174
+ * Get default view for an object and type
639
1175
  */
640
- getDefault(objectName) {
641
- const views = this.getByObjectName(objectName);
1176
+ getDefault(objectName, type) {
1177
+ const views = this.getByObjectNameAndType(objectName, type);
642
1178
  return views.find((v) => v.default) ?? views[0];
643
1179
  }
644
1180
  /**
@@ -647,20 +1183,21 @@ Available views: ${availableNames}`
647
1183
  clear() {
648
1184
  this.views.clear();
649
1185
  this.byObject.clear();
1186
+ this.byObjectAndType.clear();
650
1187
  }
651
1188
  /**
652
1189
  * Generate summary string for debugging
653
1190
  */
654
1191
  summary() {
655
1192
  const lines = [];
656
- lines.push(`[ViewRegistry] ${this.size} native view(s) registered:`);
1193
+ lines.push(`[ViewRegistry] ${this.size} view(s) registered:`);
657
1194
  for (const objectName of this.listObjectNames()) {
658
1195
  const views = this.getByObjectName(objectName);
659
1196
  const viewNames = views.map((v) => {
660
1197
  const flags = [];
661
1198
  if (v.default) flags.push("default");
662
1199
  const flagStr = flags.length > 0 ? ` (${flags.join(", ")})` : "";
663
- return `${v.name}${flagStr}`;
1200
+ return `${v.name}:${v.type}${flagStr}`;
664
1201
  });
665
1202
  lines.push(` ${objectName}: ${viewNames.join(", ")}`);
666
1203
  }
@@ -672,11 +1209,289 @@ Available views: ${availableNames}`
672
1209
  debug() {
673
1210
  console.info(this.summary());
674
1211
  }
675
- makeKey(objectName, viewName) {
676
- return `${objectName}:${viewName}`;
1212
+ makeKey(objectName, viewName, type) {
1213
+ return `${objectName}:${viewName}:${type}`;
677
1214
  }
678
1215
  };
679
1216
  var viewRegistry = new ViewRegistry();
1217
+
1218
+ // src/views/auto-generator.ts
1219
+ function getVisibleAttributes(attributes, excludeNames = []) {
1220
+ return attributes.filter(
1221
+ (attr) => !(attr.hidden || attr.archived || attr.system || excludeNames.includes(attr.name))
1222
+ );
1223
+ }
1224
+ function sortAttributes(attributes) {
1225
+ return [...attributes].sort((a, b) => {
1226
+ const orderA = a.order ?? 999;
1227
+ const orderB = b.order ?? 999;
1228
+ if (orderA !== orderB) return orderA - orderB;
1229
+ return a.name.localeCompare(b.name);
1230
+ });
1231
+ }
1232
+ function getDefaultFieldSpan(type) {
1233
+ switch (type) {
1234
+ case "textarea":
1235
+ case "richtext":
1236
+ case "location":
1237
+ return 12;
1238
+ case "checkbox":
1239
+ return 4;
1240
+ default:
1241
+ return 6;
1242
+ }
1243
+ }
1244
+ function attributeToField(attr) {
1245
+ return {
1246
+ attribute: attr.name,
1247
+ span: getDefaultFieldSpan(attr.type)
1248
+ };
1249
+ }
1250
+ function generateDefaultDetailView(object2, options = {}) {
1251
+ const {
1252
+ includeActivityTab = true,
1253
+ includeNotesTab = true,
1254
+ includeDocumentsTab = true,
1255
+ includeFlowsTab = false,
1256
+ excludeAttributes = []
1257
+ } = options;
1258
+ const visibleAttrs = getVisibleAttributes(object2.attributes, excludeAttributes);
1259
+ const sortedAttrs = sortAttributes(visibleAttrs);
1260
+ const formTab = {
1261
+ id: "form",
1262
+ name: "form",
1263
+ label: "Details",
1264
+ type: "form",
1265
+ groups: [
1266
+ {
1267
+ id: "general",
1268
+ label: "General",
1269
+ fields: sortedAttrs.map(attributeToField),
1270
+ order: 0
1271
+ }
1272
+ ],
1273
+ order: 0
1274
+ };
1275
+ const tabs = [formTab];
1276
+ let tabOrder = 1;
1277
+ const hasDocuments = object2.attributes.some((attr) => attr.type === "document");
1278
+ if (includeDocumentsTab && hasDocuments) {
1279
+ tabs.push({
1280
+ id: "documents",
1281
+ name: "documents",
1282
+ label: "Documents",
1283
+ type: "documents",
1284
+ order: tabOrder++,
1285
+ allowUpload: true,
1286
+ allowRemove: true,
1287
+ showProcessing: true
1288
+ });
1289
+ }
1290
+ if (includeActivityTab) {
1291
+ tabs.push({
1292
+ id: "activity",
1293
+ name: "activity",
1294
+ label: "Activity",
1295
+ type: "activity",
1296
+ order: tabOrder++
1297
+ });
1298
+ }
1299
+ if (includeNotesTab) {
1300
+ tabs.push({
1301
+ id: "notes",
1302
+ name: "notes",
1303
+ label: "Notes",
1304
+ type: "notes",
1305
+ order: tabOrder++,
1306
+ allowCreate: true
1307
+ });
1308
+ }
1309
+ if (includeFlowsTab) {
1310
+ tabs.push({
1311
+ id: "flows",
1312
+ name: "flows",
1313
+ label: "Workflows",
1314
+ type: "flows",
1315
+ order: tabOrder++,
1316
+ allowStart: true,
1317
+ allowCancel: true
1318
+ });
1319
+ }
1320
+ const config = {
1321
+ layout: "page",
1322
+ tabs
1323
+ };
1324
+ return {
1325
+ name: "default",
1326
+ label: "Default View",
1327
+ object: object2.name,
1328
+ type: "detail",
1329
+ config,
1330
+ default: true
1331
+ };
1332
+ }
1333
+ function generateDefaultListView(object2, options = {}) {
1334
+ const { excludeAttributes = [], maxListColumns = 5 } = options;
1335
+ const visibleAttrs = getVisibleAttributes(object2.attributes, excludeAttributes);
1336
+ const sortedAttrs = sortAttributes(visibleAttrs);
1337
+ const columns = sortedAttrs.slice(0, maxListColumns).map((attr) => attr.name);
1338
+ const config = {
1339
+ layout: "table",
1340
+ columns
1341
+ };
1342
+ return {
1343
+ name: "default",
1344
+ label: "All Records",
1345
+ object: object2.name,
1346
+ type: "list",
1347
+ config,
1348
+ default: true
1349
+ };
1350
+ }
1351
+ function generateFallbackView(object2, type, options = {}) {
1352
+ switch (type) {
1353
+ case "detail":
1354
+ return generateDefaultDetailView(object2, options);
1355
+ case "list":
1356
+ return generateDefaultListView(object2, options);
1357
+ default:
1358
+ throw new Error(`Fallback generation not supported for view type: ${type}`);
1359
+ }
1360
+ }
1361
+
1362
+ // src/views/view-reset.ts
1363
+ function getPreservedDetailTabs(view2, options) {
1364
+ const { preserveCustomTabs = true, preserveTableTabs = true } = options;
1365
+ const preserved = [];
1366
+ for (const tab of view2.config.tabs) {
1367
+ if (preserveCustomTabs && tab.type === "custom") {
1368
+ preserved.push(tab);
1369
+ }
1370
+ if (preserveTableTabs && tab.type === "table") {
1371
+ preserved.push(tab);
1372
+ }
1373
+ }
1374
+ return preserved;
1375
+ }
1376
+ function mergeDetailTabs(generatedTabs, preservedTabs) {
1377
+ if (preservedTabs.length === 0) {
1378
+ return generatedTabs;
1379
+ }
1380
+ const formTab = generatedTabs.find((t) => t.type === "form");
1381
+ const otherTabs = generatedTabs.filter((t) => t.type !== "form");
1382
+ const result = [];
1383
+ if (formTab) {
1384
+ result.push(formTab);
1385
+ }
1386
+ let order = 1;
1387
+ for (const tab of preservedTabs) {
1388
+ result.push({ ...tab, order: order++ });
1389
+ }
1390
+ for (const tab of otherTabs) {
1391
+ result.push({ ...tab, order: order++ });
1392
+ }
1393
+ return result;
1394
+ }
1395
+ function resetDetailViewToDefault(view2, object2, options) {
1396
+ const { preserveMetadata = true, ...generateOptions } = options;
1397
+ const defaultView = generateDefaultDetailView(object2, generateOptions);
1398
+ const preservedTabs = getPreservedDetailTabs(view2, options);
1399
+ const mergedTabs = mergeDetailTabs(defaultView.config.tabs, preservedTabs);
1400
+ const config = {
1401
+ ...defaultView.config,
1402
+ tabs: mergedTabs
1403
+ };
1404
+ const resetView = {
1405
+ ...defaultView,
1406
+ config
1407
+ };
1408
+ if (preserveMetadata) {
1409
+ resetView.id = view2.id;
1410
+ resetView.name = view2.name;
1411
+ resetView.label = view2.label;
1412
+ resetView.description = view2.description;
1413
+ resetView.icon = view2.icon;
1414
+ }
1415
+ return resetView;
1416
+ }
1417
+ function resetListViewToDefault(view2, object2, options) {
1418
+ const { preserveMetadata = true, ...generateOptions } = options;
1419
+ const defaultView = generateDefaultListView(object2, generateOptions);
1420
+ const resetView = {
1421
+ ...defaultView
1422
+ };
1423
+ if (preserveMetadata) {
1424
+ resetView.id = view2.id;
1425
+ resetView.name = view2.name;
1426
+ resetView.label = view2.label;
1427
+ resetView.description = view2.description;
1428
+ resetView.icon = view2.icon;
1429
+ }
1430
+ return resetView;
1431
+ }
1432
+ function resetViewToDefault(currentView, object2, options = {}) {
1433
+ if (isDetailView(currentView)) {
1434
+ return resetDetailViewToDefault(currentView, object2, options);
1435
+ }
1436
+ if (isListView(currentView)) {
1437
+ return resetListViewToDefault(currentView, object2, options);
1438
+ }
1439
+ throw new Error(`Reset not supported for view type: ${currentView.type}`);
1440
+ }
1441
+ function isDetailViewCustomized(view2, object2) {
1442
+ const defaultView = generateDefaultDetailView(object2);
1443
+ const viewFormTab = view2.config.tabs.find((t) => t.type === "form");
1444
+ const defaultFormTab = defaultView.config.tabs.find((t) => t.type === "form");
1445
+ if (!(viewFormTab && defaultFormTab)) {
1446
+ return true;
1447
+ }
1448
+ if (viewFormTab.type !== "form" || defaultFormTab.type !== "form") {
1449
+ return true;
1450
+ }
1451
+ if (viewFormTab.groups.length !== defaultFormTab.groups.length) {
1452
+ return true;
1453
+ }
1454
+ for (let i = 0; i < viewFormTab.groups.length; i++) {
1455
+ const viewGroup = viewFormTab.groups[i];
1456
+ const defaultGroup = defaultFormTab.groups[i];
1457
+ if (viewGroup.id !== defaultGroup.id) {
1458
+ return true;
1459
+ }
1460
+ if (viewGroup.fields.length !== defaultGroup.fields.length) {
1461
+ return true;
1462
+ }
1463
+ for (let j = 0; j < viewGroup.fields.length; j++) {
1464
+ if (viewGroup.fields[j].attribute !== defaultGroup.fields[j].attribute) {
1465
+ return true;
1466
+ }
1467
+ }
1468
+ }
1469
+ return false;
1470
+ }
1471
+ function isListViewCustomized(view2, object2) {
1472
+ const defaultView = generateDefaultListView(object2);
1473
+ if (view2.config.columns.length !== defaultView.config.columns.length) {
1474
+ return true;
1475
+ }
1476
+ for (let i = 0; i < view2.config.columns.length; i++) {
1477
+ if (view2.config.columns[i] !== defaultView.config.columns[i]) {
1478
+ return true;
1479
+ }
1480
+ }
1481
+ if (view2.config.layout !== defaultView.config.layout) {
1482
+ return true;
1483
+ }
1484
+ return false;
1485
+ }
1486
+ function isViewCustomized(view2, object2) {
1487
+ if (isDetailView(view2)) {
1488
+ return isDetailViewCustomized(view2, object2);
1489
+ }
1490
+ if (isListView(view2)) {
1491
+ return isListViewCustomized(view2, object2);
1492
+ }
1493
+ return true;
1494
+ }
680
1495
  export {
681
1496
  ALL_SYSTEM_RESOURCES,
682
1497
  ActivityTabConfig,
@@ -684,6 +1499,7 @@ export {
684
1499
  AttributeNotFoundError,
685
1500
  AuditService,
686
1501
  AuthMethodSchema,
1502
+ BEHAVIOR_PROPERTIES,
687
1503
  BaseRepository,
688
1504
  BaseService,
689
1505
  ConcurrentModificationError,
@@ -702,6 +1518,7 @@ export {
702
1518
  DEFAULT_THEME,
703
1519
  DEFAULT_VALIDATION_MESSAGES,
704
1520
  DRIVING_LICENSE,
1521
+ DetailViewBuilder,
705
1522
  DirectTableTabConfig,
706
1523
  DocumentExecutor,
707
1524
  DocumentGenerationNotConfiguredError,
@@ -721,8 +1538,11 @@ export {
721
1538
  EndNodeSchema,
722
1539
  ExecutorRegistry,
723
1540
  FRENCH_ID_CARD,
1541
+ FeatureFlagsContextError,
724
1542
  FileNotFoundError,
725
1543
  FileService,
1544
+ FlagRegistry,
1545
+ FlagService,
726
1546
  FlowRowFieldSchema,
727
1547
  FlowRowSchema,
728
1548
  FlowsTabConfig,
@@ -738,12 +1558,15 @@ export {
738
1558
  GrantNotFoundError,
739
1559
  GrantRevokedError,
740
1560
  GroupBuilder,
1561
+ IDENTITY_PROPERTIES,
741
1562
  InvalidPathError,
742
1563
  InverseTableTabConfig,
743
1564
  InvitationAlreadyAcceptedError,
744
1565
  InvitationExpiredError,
745
1566
  InvitationNotFoundError,
746
1567
  InvitationRevokedError,
1568
+ ListViewBuilder,
1569
+ ListViewTabConfigBuilder,
747
1570
  MaxDepthExceededError,
748
1571
  NOTES,
749
1572
  NO_VALUE_OPERATORS,
@@ -760,6 +1583,7 @@ export {
760
1583
  ObjectReferencedError,
761
1584
  ObjectSchemaService,
762
1585
  PASSPORT,
1586
+ PRESENTATION_PROPERTIES,
763
1587
  PROOF_OF_ADDRESS,
764
1588
  PermissionService,
765
1589
  PolicyRegistry,
@@ -836,6 +1660,7 @@ export {
836
1660
  asTenantId,
837
1661
  asUserId,
838
1662
  attributeConfigSchemas,
1663
+ booleanFlag,
839
1664
  buildAuditChanges,
840
1665
  buildPolicyContext,
841
1666
  cacheKeys,
@@ -866,6 +1691,8 @@ export {
866
1691
  createDraftValidator,
867
1692
  createEmptyContext,
868
1693
  createFileValidator,
1694
+ createFlagRegistry,
1695
+ createFlagService,
869
1696
  createFormAttributeValidator,
870
1697
  createFormulaValidator,
871
1698
  createLocationValidator,
@@ -893,6 +1720,7 @@ export {
893
1720
  dateConfigSchema,
894
1721
  defaultPolicyRegistry,
895
1722
  defaultTtl,
1723
+ detailView,
896
1724
  document,
897
1725
  documentConfigSchema,
898
1726
  enrichRecordsWithFormulas,
@@ -916,14 +1744,19 @@ export {
916
1744
  extractRelationReferences,
917
1745
  file,
918
1746
  fileConfigSchema,
1747
+ flagRegistry,
919
1748
  flattenRelationsForEval,
920
1749
  formatAttributeValue,
921
1750
  formatFormulaResult,
922
1751
  formatRecord,
923
1752
  formatRecords,
1753
+ formatZodErrors,
924
1754
  formula,
925
1755
  formulaConfigSchema,
926
1756
  generateCssVariables,
1757
+ generateDefaultDetailView,
1758
+ generateDefaultListView,
1759
+ generateFallbackView,
927
1760
  generateId,
928
1761
  generatePrefixedId,
929
1762
  generateTemplateName,
@@ -931,6 +1764,8 @@ export {
931
1764
  getContext,
932
1765
  getContextValue,
933
1766
  getDefaultExecutorRegistry,
1767
+ getFeatureFlags,
1768
+ getFeatureValue,
934
1769
  getMissingRequiredAttributes,
935
1770
  getNodeOutputs,
936
1771
  getPathDepth,
@@ -945,37 +1780,44 @@ export {
945
1780
  getTargetAttributeName,
946
1781
  getTenantId,
947
1782
  getUserId,
1783
+ getViewSeedPreview,
948
1784
  getViewSyncPreview,
949
1785
  group,
950
1786
  hasContext,
1787
+ hasFeatureFlagsContext,
1788
+ hasProperties,
951
1789
  hasRelationReferences,
952
1790
  hasSchemaContext,
953
1791
  hashOptions,
954
1792
  inValues,
1793
+ indexBy,
955
1794
  isActivityTab,
956
- isAdvancedFilterState,
957
1795
  isAdvancedFormNode,
958
- isConcurrentModificationError,
1796
+ isBehaviorProperty,
1797
+ isCalendarView,
959
1798
  isConditionGroup,
960
1799
  isConditionNode,
961
1800
  isConditionRule,
962
1801
  isCustomTab,
963
1802
  isDefaultRole,
1803
+ isDetailView,
964
1804
  isDirectTableTab,
965
1805
  isDocumentNode,
966
1806
  isDocumentsTab,
967
- isDocxTemplateSource,
968
1807
  isEmpty,
969
1808
  isEndNode,
1809
+ isFeatureEnabled,
970
1810
  isFlowDefinition,
971
1811
  isFlowPublished,
972
1812
  isFlowsTab,
973
1813
  isForbiddenError,
974
1814
  isFormNode,
975
1815
  isFormTab,
1816
+ isGalleryView,
976
1817
  isGrantExpired,
977
1818
  isGrantRevoked,
978
1819
  isGrantValid,
1820
+ isIdentityProperty,
979
1821
  isInstanceEvent,
980
1822
  isInstanceTerminal,
981
1823
  isInstanceWaiting,
@@ -985,12 +1827,13 @@ export {
985
1827
  isInvitationOrGrantEvent,
986
1828
  isInvitationValid,
987
1829
  isLabelExpression,
1830
+ isListView,
988
1831
  isNoValueOperator,
989
1832
  isNodeEvent,
990
1833
  isNotEmpty,
991
1834
  isNotFoundError,
992
1835
  isNotesTab,
993
- isPdfTemplateSource,
1836
+ isPresentationProperty,
994
1837
  isProtectedResourceError,
995
1838
  isRecordComplete,
996
1839
  isSchemaError,
@@ -1002,14 +1845,17 @@ export {
1002
1845
  isSystemTemplate,
1003
1846
  isSystemWorkflow,
1004
1847
  isTableTab,
1848
+ isTimelineView,
1005
1849
  isTokenRevoked,
1006
1850
  isUniversalRelation,
1007
1851
  isValidationError,
1852
+ isViewCustomized,
1008
1853
  isWorkflowDefinition,
1009
1854
  isWorkflowPublished,
1855
+ jsonFlag,
1856
+ listView,
1010
1857
  location,
1011
1858
  locationConfigSchema,
1012
- mergeFormToSlot,
1013
1859
  mergeWithDefaults,
1014
1860
  multiselect,
1015
1861
  multiselectConfigSchema,
@@ -1017,6 +1863,7 @@ export {
1017
1863
  notesPolicy,
1018
1864
  number,
1019
1865
  numberConfigSchema,
1866
+ numberFlag,
1020
1867
  object,
1021
1868
  or,
1022
1869
  parseAttributeConfig,
@@ -1031,6 +1878,7 @@ export {
1031
1878
  relation,
1032
1879
  relationConfigSchema,
1033
1880
  renderLabelExpression,
1881
+ resetViewToDefault,
1034
1882
  resolveMultiplePaths,
1035
1883
  resolveSingleValue,
1036
1884
  richtext,
@@ -1038,15 +1886,18 @@ export {
1038
1886
  rollup,
1039
1887
  rollupConfigSchema,
1040
1888
  runWithContext,
1889
+ runWithFeatureFlags,
1041
1890
  runWithMergedSchemaContext,
1042
1891
  runWithSchemaContext,
1043
1892
  safeParseAttributeConfig,
1893
+ seedRegistryViews,
1044
1894
  select,
1045
1895
  selectConfigSchema,
1046
1896
  setContextValue,
1047
1897
  slugify,
1048
1898
  status,
1049
1899
  statusConfigSchema,
1900
+ stringFlag,
1050
1901
  success,
1051
1902
  syncAll,
1052
1903
  syncNativeObjects,
@@ -1055,9 +1906,9 @@ export {
1055
1906
  textConfigSchema,
1056
1907
  textarea,
1057
1908
  textareaConfigSchema,
1058
- toAdvancedFilterState,
1059
- toSimpleFilterState,
1909
+ toUndefinedIfEmpty,
1060
1910
  traversePath,
1911
+ tryGetFeatureValue,
1061
1912
  user,
1062
1913
  userConfigSchema,
1063
1914
  validateAttribute,
@@ -1070,9 +1921,11 @@ export {
1070
1921
  validatePath,
1071
1922
  verifyNativeObjectsSync,
1072
1923
  verifyNativeViewsSync,
1924
+ verifyRegistryViewsSeeded,
1073
1925
  view,
1074
1926
  viewRegistry,
1075
1927
  wait,
1928
+ withFeatureFlags,
1076
1929
  withTenantContext,
1077
1930
  workflow
1078
1931
  };