@happyvertical/smrt-fields 0.40.59 → 0.40.61

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 (184) hide show
  1. package/AGENTS.md +58 -12
  2. package/README.md +90 -2
  3. package/dist/__smrt-register__.d.ts +2 -0
  4. package/dist/__smrt-register__.d.ts.map +1 -0
  5. package/dist/cache.d.ts +18 -0
  6. package/dist/cache.d.ts.map +1 -0
  7. package/dist/collections/FieldPolicyCollection.d.ts +95 -0
  8. package/dist/collections/FieldPolicyCollection.d.ts.map +1 -0
  9. package/dist/field-definitions.d.ts +77 -0
  10. package/dist/field-definitions.d.ts.map +1 -0
  11. package/dist/field-policy-resolver.d.ts +46 -0
  12. package/dist/field-policy-resolver.d.ts.map +1 -0
  13. package/dist/index.d.ts +9 -532
  14. package/dist/index.d.ts.map +1 -0
  15. package/dist/index.js +752 -55
  16. package/dist/index.js.map +1 -1
  17. package/dist/manifest.json +45 -3
  18. package/dist/models/FieldPolicy.d.ts +163 -0
  19. package/dist/models/FieldPolicy.d.ts.map +1 -0
  20. package/dist/permissions.d.ts +9 -0
  21. package/dist/permissions.d.ts.map +1 -0
  22. package/dist/playground.d.ts +2 -0
  23. package/dist/playground.d.ts.map +1 -0
  24. package/dist/playground.js +39 -0
  25. package/dist/playground.js.map +1 -0
  26. package/dist/settings-catalog.d.ts +73 -0
  27. package/dist/settings-catalog.d.ts.map +1 -0
  28. package/dist/smrt-knowledge.json +50 -7
  29. package/dist/svelte/__tests__/FieldPolicyControlPanel.test.js +223 -0
  30. package/dist/svelte/__tests__/FieldPolicyGear.test.js +503 -0
  31. package/dist/svelte/__tests__/FormHelp.test.js +138 -0
  32. package/dist/svelte/__tests__/ModeUX.test.js +109 -0
  33. package/dist/svelte/__tests__/ObjectForm.test.js +556 -0
  34. package/dist/svelte/__tests__/ObjectFormGeneratedApi.integration.test.js +436 -0
  35. package/dist/svelte/__tests__/PolicyField.test.js +373 -0
  36. package/dist/svelte/__tests__/fixtures/AdvancedFieldsFixture.svelte +30 -0
  37. package/dist/svelte/__tests__/fixtures/AdvancedFieldsFixture.svelte.d.ts +9 -0
  38. package/dist/svelte/__tests__/fixtures/AdvancedFieldsFixture.svelte.d.ts.map +1 -0
  39. package/dist/svelte/__tests__/fixtures/DomPrefillFixture.svelte +33 -0
  40. package/dist/svelte/__tests__/fixtures/DomPrefillFixture.svelte.d.ts +10 -0
  41. package/dist/svelte/__tests__/fixtures/DomPrefillFixture.svelte.d.ts.map +1 -0
  42. package/dist/svelte/__tests__/fixtures/FormHelpFixture.svelte +19 -0
  43. package/dist/svelte/__tests__/fixtures/FormHelpFixture.svelte.d.ts +10 -0
  44. package/dist/svelte/__tests__/fixtures/FormHelpFixture.svelte.d.ts.map +1 -0
  45. package/dist/svelte/__tests__/fixtures/GeneratedApiGearFixture.svelte +18 -0
  46. package/dist/svelte/__tests__/fixtures/GeneratedApiGearFixture.svelte.d.ts +11 -0
  47. package/dist/svelte/__tests__/fixtures/GeneratedApiGearFixture.svelte.d.ts.map +1 -0
  48. package/dist/svelte/__tests__/fixtures/GracefulDegradeFixture.svelte +11 -0
  49. package/dist/svelte/__tests__/fixtures/GracefulDegradeFixture.svelte.d.ts +19 -0
  50. package/dist/svelte/__tests__/fixtures/GracefulDegradeFixture.svelte.d.ts.map +1 -0
  51. package/dist/svelte/__tests__/fixtures/ModeSwitchFixture.svelte +18 -0
  52. package/dist/svelte/__tests__/fixtures/ModeSwitchFixture.svelte.d.ts +8 -0
  53. package/dist/svelte/__tests__/fixtures/ModeSwitchFixture.svelte.d.ts.map +1 -0
  54. package/dist/svelte/__tests__/fixtures/NoIdFixture.svelte +24 -0
  55. package/dist/svelte/__tests__/fixtures/NoIdFixture.svelte.d.ts +13 -0
  56. package/dist/svelte/__tests__/fixtures/NoIdFixture.svelte.d.ts.map +1 -0
  57. package/dist/svelte/__tests__/fixtures/ObjectFormActionsFixture.svelte +20 -0
  58. package/dist/svelte/__tests__/fixtures/ObjectFormActionsFixture.svelte.d.ts +11 -0
  59. package/dist/svelte/__tests__/fixtures/ObjectFormActionsFixture.svelte.d.ts.map +1 -0
  60. package/dist/svelte/__tests__/fixtures/ObjectFormFixture.svelte +17 -0
  61. package/dist/svelte/__tests__/fixtures/ObjectFormFixture.svelte.d.ts +10 -0
  62. package/dist/svelte/__tests__/fixtures/ObjectFormFixture.svelte.d.ts.map +1 -0
  63. package/dist/svelte/__tests__/fixtures/ObjectFormRegistryFixture.svelte +25 -0
  64. package/dist/svelte/__tests__/fixtures/ObjectFormRegistryFixture.svelte.d.ts +10 -0
  65. package/dist/svelte/__tests__/fixtures/ObjectFormRegistryFixture.svelte.d.ts.map +1 -0
  66. package/dist/svelte/__tests__/fixtures/ObjectFormSnippetFixture.svelte +34 -0
  67. package/dist/svelte/__tests__/fixtures/ObjectFormSnippetFixture.svelte.d.ts +10 -0
  68. package/dist/svelte/__tests__/fixtures/ObjectFormSnippetFixture.svelte.d.ts.map +1 -0
  69. package/dist/svelte/__tests__/fixtures/ObjectFormSourceFixture.svelte +29 -0
  70. package/dist/svelte/__tests__/fixtures/ObjectFormSourceFixture.svelte.d.ts +11 -0
  71. package/dist/svelte/__tests__/fixtures/ObjectFormSourceFixture.svelte.d.ts.map +1 -0
  72. package/dist/svelte/__tests__/fixtures/ObjectFormSourceSnippetFixture.svelte +33 -0
  73. package/dist/svelte/__tests__/fixtures/ObjectFormSourceSnippetFixture.svelte.d.ts +9 -0
  74. package/dist/svelte/__tests__/fixtures/ObjectFormSourceSnippetFixture.svelte.d.ts.map +1 -0
  75. package/dist/svelte/__tests__/fixtures/PolicyDataTableFixture.svelte +40 -0
  76. package/dist/svelte/__tests__/fixtures/PolicyDataTableFixture.svelte.d.ts +8 -0
  77. package/dist/svelte/__tests__/fixtures/PolicyDataTableFixture.svelte.d.ts.map +1 -0
  78. package/dist/svelte/__tests__/fixtures/PrefillFixture.svelte +26 -0
  79. package/dist/svelte/__tests__/fixtures/PrefillFixture.svelte.d.ts +13 -0
  80. package/dist/svelte/__tests__/fixtures/PrefillFixture.svelte.d.ts.map +1 -0
  81. package/dist/svelte/__tests__/fixtures/ProviderFieldFixture.svelte +39 -0
  82. package/dist/svelte/__tests__/fixtures/ProviderFieldFixture.svelte.d.ts +17 -0
  83. package/dist/svelte/__tests__/fixtures/ProviderFieldFixture.svelte.d.ts.map +1 -0
  84. package/dist/svelte/__tests__/fixtures/RegistryInput.svelte +15 -0
  85. package/dist/svelte/__tests__/fixtures/RegistryInput.svelte.d.ts +5 -0
  86. package/dist/svelte/__tests__/fixtures/RegistryInput.svelte.d.ts.map +1 -0
  87. package/dist/svelte/__tests__/fixtures/RevealPrefillFixture.svelte +29 -0
  88. package/dist/svelte/__tests__/fixtures/RevealPrefillFixture.svelte.d.ts +14 -0
  89. package/dist/svelte/__tests__/fixtures/RevealPrefillFixture.svelte.d.ts.map +1 -0
  90. package/dist/svelte/__tests__/fixtures/SettingsCatalogStub.svelte +24 -0
  91. package/dist/svelte/__tests__/fixtures/SettingsCatalogStub.svelte.d.ts +14 -0
  92. package/dist/svelte/__tests__/fixtures/SettingsCatalogStub.svelte.d.ts.map +1 -0
  93. package/dist/svelte/__tests__/fixtures/SnippetFixture.svelte +28 -0
  94. package/dist/svelte/__tests__/fixtures/SnippetFixture.svelte.d.ts +13 -0
  95. package/dist/svelte/__tests__/fixtures/SnippetFixture.svelte.d.ts.map +1 -0
  96. package/dist/svelte/__tests__/fixtures/ToggleModeButton.svelte +14 -0
  97. package/dist/svelte/__tests__/fixtures/ToggleModeButton.svelte.d.ts +19 -0
  98. package/dist/svelte/__tests__/fixtures/ToggleModeButton.svelte.d.ts.map +1 -0
  99. package/dist/svelte/__tests__/fixtures/TooltipFixture.svelte +25 -0
  100. package/dist/svelte/__tests__/fixtures/TooltipFixture.svelte.d.ts +14 -0
  101. package/dist/svelte/__tests__/fixtures/TooltipFixture.svelte.d.ts.map +1 -0
  102. package/dist/svelte/__tests__/settings-catalog.test.js +161 -0
  103. package/dist/svelte/components/AdvancedFields.svelte +49 -0
  104. package/dist/svelte/components/AdvancedFields.svelte.d.ts +17 -0
  105. package/dist/svelte/components/AdvancedFields.svelte.d.ts.map +1 -0
  106. package/dist/svelte/components/FieldInput.svelte +159 -0
  107. package/dist/svelte/components/FieldInput.svelte.d.ts +5 -0
  108. package/dist/svelte/components/FieldInput.svelte.d.ts.map +1 -0
  109. package/dist/svelte/components/FieldPolicyControlPanel.svelte +261 -0
  110. package/dist/svelte/components/FieldPolicyControlPanel.svelte.d.ts +26 -0
  111. package/dist/svelte/components/FieldPolicyControlPanel.svelte.d.ts.map +1 -0
  112. package/dist/svelte/components/FieldPolicyEditor.svelte +417 -0
  113. package/dist/svelte/components/FieldPolicyEditor.svelte.d.ts +18 -0
  114. package/dist/svelte/components/FieldPolicyEditor.svelte.d.ts.map +1 -0
  115. package/dist/svelte/components/FieldPolicyGearButton.svelte +17 -0
  116. package/dist/svelte/components/FieldPolicyGearButton.svelte.d.ts +8 -0
  117. package/dist/svelte/components/FieldPolicyGearButton.svelte.d.ts.map +1 -0
  118. package/dist/svelte/components/FieldPolicyGearProvider.svelte +135 -0
  119. package/dist/svelte/components/FieldPolicyGearProvider.svelte.d.ts +17 -0
  120. package/dist/svelte/components/FieldPolicyGearProvider.svelte.d.ts.map +1 -0
  121. package/dist/svelte/components/FieldPolicyProvider.svelte +89 -0
  122. package/dist/svelte/components/FieldPolicyProvider.svelte.d.ts +35 -0
  123. package/dist/svelte/components/FieldPolicyProvider.svelte.d.ts.map +1 -0
  124. package/dist/svelte/components/FormHelp.svelte +157 -0
  125. package/dist/svelte/components/FormHelp.svelte.d.ts +15 -0
  126. package/dist/svelte/components/FormHelp.svelte.d.ts.map +1 -0
  127. package/dist/svelte/components/ModeSwitch.svelte +47 -0
  128. package/dist/svelte/components/ModeSwitch.svelte.d.ts +10 -0
  129. package/dist/svelte/components/ModeSwitch.svelte.d.ts.map +1 -0
  130. package/dist/svelte/components/ObjectForm.svelte +351 -0
  131. package/dist/svelte/components/ObjectForm.svelte.d.ts +40 -0
  132. package/dist/svelte/components/ObjectForm.svelte.d.ts.map +1 -0
  133. package/dist/svelte/components/ObjectFormSourceProvider.svelte +18 -0
  134. package/dist/svelte/components/ObjectFormSourceProvider.svelte.d.ts +11 -0
  135. package/dist/svelte/components/ObjectFormSourceProvider.svelte.d.ts.map +1 -0
  136. package/dist/svelte/components/PolicyField.svelte +338 -0
  137. package/dist/svelte/components/PolicyField.svelte.d.ts +80 -0
  138. package/dist/svelte/components/PolicyField.svelte.d.ts.map +1 -0
  139. package/dist/svelte/context.svelte.d.ts +54 -0
  140. package/dist/svelte/context.svelte.d.ts.map +1 -0
  141. package/dist/svelte/context.svelte.js +55 -0
  142. package/dist/svelte/data-table.d.ts +17 -0
  143. package/dist/svelte/data-table.d.ts.map +1 -0
  144. package/dist/svelte/data-table.js +19 -0
  145. package/dist/svelte/field-policy-editor.d.ts +81 -0
  146. package/dist/svelte/field-policy-editor.d.ts.map +1 -0
  147. package/dist/svelte/field-policy-editor.js +120 -0
  148. package/dist/svelte/gear-context.svelte.d.ts +14 -0
  149. package/dist/svelte/gear-context.svelte.d.ts.map +1 -0
  150. package/dist/svelte/gear-context.svelte.js +15 -0
  151. package/dist/svelte/index.d.ts +58 -0
  152. package/dist/svelte/index.d.ts.map +1 -0
  153. package/dist/svelte/index.js +38 -0
  154. package/dist/svelte/input-registry.d.ts +21 -0
  155. package/dist/svelte/input-registry.d.ts.map +1 -0
  156. package/dist/svelte/input-registry.js +26 -0
  157. package/dist/svelte/object-form-source-context.svelte.d.ts +4 -0
  158. package/dist/svelte/object-form-source-context.svelte.d.ts.map +1 -0
  159. package/dist/svelte/object-form-source-context.svelte.js +8 -0
  160. package/dist/svelte/object-form-source.svelte.d.ts +18 -0
  161. package/dist/svelte/object-form-source.svelte.d.ts.map +1 -0
  162. package/dist/svelte/object-form-source.svelte.js +99 -0
  163. package/dist/svelte/object-form.d.ts +6 -0
  164. package/dist/svelte/object-form.d.ts.map +1 -0
  165. package/dist/svelte/object-form.js +38 -0
  166. package/dist/svelte/playground/FieldPolicyFormPreview.svelte +212 -0
  167. package/dist/svelte/playground/FieldPolicyFormPreview.svelte.d.ts +4 -0
  168. package/dist/svelte/playground/FieldPolicyFormPreview.svelte.d.ts.map +1 -0
  169. package/dist/svelte/playground/ObjectFormPreview.svelte +129 -0
  170. package/dist/svelte/playground/ObjectFormPreview.svelte.d.ts +4 -0
  171. package/dist/svelte/playground/ObjectFormPreview.svelte.d.ts.map +1 -0
  172. package/dist/svelte/playground.d.ts +20 -0
  173. package/dist/svelte/playground.d.ts.map +1 -0
  174. package/dist/svelte/playground.js +38 -0
  175. package/dist/svelte/settings-catalog.d.ts +54 -0
  176. package/dist/svelte/settings-catalog.d.ts.map +1 -0
  177. package/dist/svelte/settings-catalog.js +116 -0
  178. package/dist/svelte/types.d.ts +101 -0
  179. package/dist/svelte/types.d.ts.map +1 -0
  180. package/dist/svelte/types.js +4 -0
  181. package/dist/types.d.ts +276 -203
  182. package/dist/types.d.ts.map +1 -0
  183. package/dist/types.js.map +1 -1
  184. package/package.json +33 -8
@@ -0,0 +1,120 @@
1
+ export function isFieldPolicyEditorState(result, expectedObjectRef) {
2
+ if (!result || typeof result !== 'object')
3
+ return false;
4
+ const candidate = result;
5
+ return (typeof candidate.capabilities?.manage === 'boolean' &&
6
+ typeof candidate.capabilities.personalize === 'boolean' &&
7
+ typeof candidate.policy?.objectRef === 'string' &&
8
+ (expectedObjectRef === undefined ||
9
+ candidate.policy.objectRef === expectedObjectRef) &&
10
+ !!candidate.policy.fields &&
11
+ !!candidate.policy.layers &&
12
+ !!candidate.personalLowerDefaultUsable &&
13
+ Object.values(candidate.personalLowerDefaultUsable).every((usable) => typeof usable === 'boolean') &&
14
+ Array.isArray(candidate.rows?.app) &&
15
+ Array.isArray(candidate.rows?.tenant) &&
16
+ Array.isArray(candidate.rows?.user));
17
+ }
18
+ /** Safe message extraction for generated custom actions, whose client type is `any`. */
19
+ export function editorStateErrorMessage(result) {
20
+ if (result &&
21
+ typeof result === 'object' &&
22
+ 'message' in result &&
23
+ typeof result.message === 'string') {
24
+ return result.message;
25
+ }
26
+ return 'Unable to load field settings.';
27
+ }
28
+ export function rowForScope(state, fieldName, scope) {
29
+ return state.rows[scope].find((row) => row.fieldName === fieldName);
30
+ }
31
+ export function draftFromRow(row) {
32
+ let defaultValue;
33
+ if (row?.defaultValue != null) {
34
+ try {
35
+ defaultValue = JSON.parse(row.defaultValue);
36
+ }
37
+ catch {
38
+ // A stale malformed row must not make the editor unusable. The server
39
+ // remains the authority and will reject a subsequently invalid save.
40
+ defaultValue = undefined;
41
+ }
42
+ }
43
+ return {
44
+ defaultEnabled: row?.defaultValue != null,
45
+ defaultValue,
46
+ displayOrder: row?.displayOrder ?? null,
47
+ help: row?.help ?? null,
48
+ label: row?.label ?? null,
49
+ locked: row?.locked ?? null,
50
+ visibility: row?.visibility ?? null,
51
+ };
52
+ }
53
+ export function mutationFromDraft(objectRef, fieldName, scopeType, draft) {
54
+ return {
55
+ objectRef,
56
+ fieldName,
57
+ scopeType,
58
+ defaultValue: draft.defaultEnabled
59
+ ? serializeDefaultValue(draft.defaultValue)
60
+ : null,
61
+ displayOrder: draft.displayOrder,
62
+ help: blankToNull(draft.help),
63
+ label: blankToNull(draft.label),
64
+ locked: scopeType === 'user' ? null : draft.locked,
65
+ visibility: draft.visibility,
66
+ };
67
+ }
68
+ /**
69
+ * Serialize the explicit default-value wire channel without ever leaking an
70
+ * `undefined` payload into a generated client. JSON null remains intentional.
71
+ */
72
+ export function serializeDefaultValue(value) {
73
+ try {
74
+ const serialized = JSON.stringify(value);
75
+ if (typeof serialized !== 'string') {
76
+ throw new Error('Choose a default value before saving this override.');
77
+ }
78
+ return serialized;
79
+ }
80
+ catch (cause) {
81
+ if (cause instanceof Error &&
82
+ cause.message.startsWith('Choose a default')) {
83
+ throw cause;
84
+ }
85
+ throw new Error('This default value cannot be saved because it is not JSON-serializable.', { cause });
86
+ }
87
+ }
88
+ export function defaultValueSerializationError(value) {
89
+ try {
90
+ serializeDefaultValue(value);
91
+ return null;
92
+ }
93
+ catch (cause) {
94
+ return cause instanceof Error
95
+ ? cause.message
96
+ : 'This default value cannot be saved.';
97
+ }
98
+ }
99
+ export function requiredVisibilityIsInvalid(required, visibility, effectiveDefault) {
100
+ return (required &&
101
+ (visibility === 'advanced' || visibility === 'hidden') &&
102
+ !hasUsableDefault(effectiveDefault));
103
+ }
104
+ export function hasUsableDefault(value) {
105
+ return value !== undefined && value !== null && value !== '';
106
+ }
107
+ function blankToNull(value) {
108
+ return value == null || value.trim() === '' ? null : value;
109
+ }
110
+ /**
111
+ * Registers an object-form settings tool with AdminShell-compatible state.
112
+ * AdminShell passes `{ tool, shell }` to a component focus tool; callers pass
113
+ * that component through `tool.component` without Fields importing the shell.
114
+ */
115
+ export function registerFieldPolicyFocusTool(shell, objectRef, tool) {
116
+ return shell.registerFocusTool({
117
+ ...tool,
118
+ subject: { type: 'object-form', id: objectRef },
119
+ });
120
+ }
@@ -0,0 +1,14 @@
1
+ import type { FieldPolicyEditorState } from '../types.js';
2
+ export interface FieldPolicyGearController {
3
+ readonly state: FieldPolicyEditorState | null;
4
+ readonly error: string | null;
5
+ readonly open: boolean;
6
+ readonly canEdit: boolean;
7
+ show(): void;
8
+ hide(): void;
9
+ reload(): Promise<void>;
10
+ }
11
+ export declare function setFieldPolicyGearContext(controller: FieldPolicyGearController): void;
12
+ export declare function getFieldPolicyGearContext(): FieldPolicyGearController;
13
+ export declare function tryGetFieldPolicyGearContext(): FieldPolicyGearController | undefined;
14
+ //# sourceMappingURL=gear-context.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gear-context.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/gear-context.svelte.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,KAAK,EAAE,sBAAsB,GAAG,IAAI,CAAC;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,IAAI,IAAI,IAAI,CAAC;IACb,IAAI,IAAI,IAAI,CAAC;IACb,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAID,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,yBAAyB,GACpC,IAAI,CAEN;AAED,wBAAgB,yBAAyB,IAAI,yBAAyB,CAQrE;AAED,wBAAgB,4BAA4B,IACxC,yBAAyB,GACzB,SAAS,CAIZ"}
@@ -0,0 +1,15 @@
1
+ import { getContext, setContext } from 'svelte';
2
+ const FIELD_POLICY_GEAR_CONTEXT = Symbol('smrt-field-policy-gear');
3
+ export function setFieldPolicyGearContext(controller) {
4
+ setContext(FIELD_POLICY_GEAR_CONTEXT, controller);
5
+ }
6
+ export function getFieldPolicyGearContext() {
7
+ const context = tryGetFieldPolicyGearContext();
8
+ if (!context) {
9
+ throw new Error('Field policy gear context not found. Wrap the form in FieldPolicyGearProvider.');
10
+ }
11
+ return context;
12
+ }
13
+ export function tryGetFieldPolicyGearContext() {
14
+ return getContext(FIELD_POLICY_GEAR_CONTEXT);
15
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @happyvertical/smrt-fields/svelte
3
+ *
4
+ * Headless form primitives for policy-driven forms (#2048). These components
5
+ * consume a pre-resolved {@link ResolvedObjectFieldPolicy} (from
6
+ * `@happyvertical/smrt-fields`) and contribute visibility-by-mode, default
7
+ * prefill, label/help rendering, and progressive disclosure — without owning
8
+ * markup or layout.
9
+ *
10
+ * The primitives are policy-source agnostic: the app passes the resolved
11
+ * policy as props (SSR `initialData` or a client fetch). No `smrt-web` import
12
+ * in the core — an optional `./web` adapter can wire live invalidation for
13
+ * apps that want it.
14
+ *
15
+ * @packageDocumentation
16
+ */
17
+ import type { ComponentProps } from 'svelte';
18
+ import AdvancedFields from './components/AdvancedFields.svelte';
19
+ import FieldPolicyControlPanel from './components/FieldPolicyControlPanel.svelte';
20
+ import FieldPolicyEditor from './components/FieldPolicyEditor.svelte';
21
+ import FieldPolicyGearButton from './components/FieldPolicyGearButton.svelte';
22
+ import FieldPolicyGearProvider from './components/FieldPolicyGearProvider.svelte';
23
+ import FieldPolicyProvider from './components/FieldPolicyProvider.svelte';
24
+ import FormHelp from './components/FormHelp.svelte';
25
+ import ModeSwitch from './components/ModeSwitch.svelte';
26
+ import ObjectForm from './components/ObjectForm.svelte';
27
+ import ObjectFormSourceProvider from './components/ObjectFormSourceProvider.svelte';
28
+ import PolicyField from './components/PolicyField.svelte';
29
+ export { AdvancedFields, FieldPolicyControlPanel, FieldPolicyEditor, FieldPolicyGearButton, FieldPolicyGearProvider, FieldPolicyProvider, FormHelp, ModeSwitch, ObjectForm, ObjectFormSourceProvider, PolicyField, };
30
+ export type AdvancedFieldsProps = ComponentProps<typeof AdvancedFields>;
31
+ export type FieldPolicyProviderProps = ComponentProps<typeof FieldPolicyProvider>;
32
+ export type FormHelpProps = ComponentProps<typeof FormHelp>;
33
+ export type ModeSwitchProps = ComponentProps<typeof ModeSwitch>;
34
+ export type ObjectFormProps = ComponentProps<typeof ObjectForm>;
35
+ export type ObjectFormSourceProviderProps = ComponentProps<typeof ObjectFormSourceProvider>;
36
+ export type FieldPolicyEditorProps = ComponentProps<typeof FieldPolicyEditor>;
37
+ export type FieldPolicyControlPanelProps = ComponentProps<typeof FieldPolicyControlPanel>;
38
+ export type FieldPolicyGearButtonProps = ComponentProps<typeof FieldPolicyGearButton>;
39
+ export type FieldPolicyGearProviderProps = ComponentProps<typeof FieldPolicyGearProvider>;
40
+ export type PolicyFieldProps = ComponentProps<typeof PolicyField>;
41
+ export type { FieldPolicyCatalogObjectSummary, FieldPolicyDetailItem, FieldPolicySettingsCatalogData, FieldPolicySettingsCatalogPage, FieldPolicySummaryItem, } from '../settings-catalog.js';
42
+ export type { ResolvedFieldPolicy, ResolvedObjectFieldPolicy, } from '../types.js';
43
+ export type { FieldPolicyContextValue, FieldPolicyMode, } from './context.svelte.js';
44
+ export { getFieldPolicyContext, setFieldPolicyContext, tryGetFieldPolicyContext, } from './context.svelte.js';
45
+ export type { PolicyDataTableColumn } from './data-table.js';
46
+ export { policyToVisibleColumnIds } from './data-table.js';
47
+ export type { FieldPolicyEditorAdapter, FieldPolicyEditorDraft, FieldPolicyEditorMutation, FieldPolicyEditorTab, FieldPolicyFocusTool, FieldPolicyFocusToolRegistrar, FieldPolicyOrganizationScope, } from './field-policy-editor.js';
48
+ export { defaultValueSerializationError, draftFromRow, editorStateErrorMessage, hasUsableDefault, isFieldPolicyEditorState, mutationFromDraft, registerFieldPolicyFocusTool, requiredVisibilityIsInvalid, rowForScope, serializeDefaultValue, } from './field-policy-editor.js';
49
+ export type { FieldPolicyGearController } from './gear-context.svelte.js';
50
+ export { getFieldPolicyGearContext, setFieldPolicyGearContext, tryGetFieldPolicyGearContext, } from './gear-context.svelte.js';
51
+ export type { FieldInputComponent } from './input-registry.js';
52
+ export { createFieldInputRegistry, FieldInputRegistry, } from './input-registry.js';
53
+ export { resolveObjectFormFields } from './object-form.js';
54
+ export { assertObjectFormCollectionDefinition, ObjectFormSourceRegistry, } from './object-form-source.svelte.js';
55
+ export type { FieldPolicyControlPanelAdapter, FieldPolicyFieldRollup, FieldPolicyLayerCell, } from './settings-catalog.js';
56
+ export { auditObjectRefs, decorateCatalogItem, decorateCatalogPage, fieldPolicyControlPanelNavItem, fieldPolicyRollup, MAX_FIELD_POLICY_AUDIT_OBJECT_REFS, orgRowIdsForObject, prunableDriftRows, } from './settings-catalog.js';
57
+ export type { FieldInputProps, ObjectFormCollectionDefinition, ObjectFormField, ObjectFormFieldDefinition, ObjectFormFieldSnippetProps, ObjectFormPolicyClient, ObjectFormResolvedSource, ObjectFormSource, ObjectFormWireType, PolicyFieldSnippetProps, } from './types.js';
58
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/svelte/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @happyvertical/smrt-fields/svelte
3
+ *
4
+ * Headless form primitives for policy-driven forms (#2048). These components
5
+ * consume a pre-resolved {@link ResolvedObjectFieldPolicy} (from
6
+ * `@happyvertical/smrt-fields`) and contribute visibility-by-mode, default
7
+ * prefill, label/help rendering, and progressive disclosure — without owning
8
+ * markup or layout.
9
+ *
10
+ * The primitives are policy-source agnostic: the app passes the resolved
11
+ * policy as props (SSR `initialData` or a client fetch). No `smrt-web` import
12
+ * in the core — an optional `./web` adapter can wire live invalidation for
13
+ * apps that want it.
14
+ *
15
+ * @packageDocumentation
16
+ */
17
+ import AdvancedFields from './components/AdvancedFields.svelte';
18
+ import FieldPolicyControlPanel from './components/FieldPolicyControlPanel.svelte';
19
+ import FieldPolicyEditor from './components/FieldPolicyEditor.svelte';
20
+ import FieldPolicyGearButton from './components/FieldPolicyGearButton.svelte';
21
+ import FieldPolicyGearProvider from './components/FieldPolicyGearProvider.svelte';
22
+ import FieldPolicyProvider from './components/FieldPolicyProvider.svelte';
23
+ import FormHelp from './components/FormHelp.svelte';
24
+ import ModeSwitch from './components/ModeSwitch.svelte';
25
+ import ObjectForm from './components/ObjectForm.svelte';
26
+ import ObjectFormSourceProvider from './components/ObjectFormSourceProvider.svelte';
27
+ import PolicyField from './components/PolicyField.svelte';
28
+ // Components
29
+ export { AdvancedFields, FieldPolicyControlPanel, FieldPolicyEditor, FieldPolicyGearButton, FieldPolicyGearProvider, FieldPolicyProvider, FormHelp, ModeSwitch, ObjectForm, ObjectFormSourceProvider, PolicyField, };
30
+ // Context types and accessors
31
+ export { getFieldPolicyContext, setFieldPolicyContext, tryGetFieldPolicyContext, } from './context.svelte.js';
32
+ export { policyToVisibleColumnIds } from './data-table.js';
33
+ export { defaultValueSerializationError, draftFromRow, editorStateErrorMessage, hasUsableDefault, isFieldPolicyEditorState, mutationFromDraft, registerFieldPolicyFocusTool, requiredVisibilityIsInvalid, rowForScope, serializeDefaultValue, } from './field-policy-editor.js';
34
+ export { getFieldPolicyGearContext, setFieldPolicyGearContext, tryGetFieldPolicyGearContext, } from './gear-context.svelte.js';
35
+ export { createFieldInputRegistry, FieldInputRegistry, } from './input-registry.js';
36
+ export { resolveObjectFormFields } from './object-form.js';
37
+ export { assertObjectFormCollectionDefinition, ObjectFormSourceRegistry, } from './object-form-source.svelte.js';
38
+ export { auditObjectRefs, decorateCatalogItem, decorateCatalogPage, fieldPolicyControlPanelNavItem, fieldPolicyRollup, MAX_FIELD_POLICY_AUDIT_OBJECT_REFS, orgRowIdsForObject, prunableDriftRows, } from './settings-catalog.js';
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Per-app input renderer registry for generated ObjectForms.
3
+ *
4
+ * Registries are deliberately constructed by each application rather than
5
+ * stored globally: one host can replace a type renderer without changing a
6
+ * second app rendered in the same browser (micro-frontends and tests are both
7
+ * common consumers). A qualified `objectRef.fieldName` registration wins over
8
+ * its wire-type registration.
9
+ */
10
+ import type { Component } from 'svelte';
11
+ import type { FieldInputProps } from './types.js';
12
+ export type FieldInputComponent = Component<FieldInputProps>;
13
+ export declare class FieldInputRegistry {
14
+ #private;
15
+ registerType(type: string, component: FieldInputComponent): () => void;
16
+ registerField(objectRef: string, fieldName: string, component: FieldInputComponent): () => void;
17
+ resolve(objectRef: string, fieldName: string, type: string): FieldInputComponent | undefined;
18
+ }
19
+ /** Create an isolated registry for one application root. */
20
+ export declare function createFieldInputRegistry(): FieldInputRegistry;
21
+ //# sourceMappingURL=input-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-registry.d.ts","sourceRoot":"","sources":["../../src/svelte/input-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD,MAAM,MAAM,mBAAmB,GAAG,SAAS,CAAC,eAAe,CAAC,CAAC;AAE7D,qBAAa,kBAAkB;;IAI7B,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,mBAAmB,GAAG,MAAM,IAAI;IAOtE,aAAa,CACX,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,mBAAmB,GAC7B,MAAM,IAAI;IAQb,OAAO,CACL,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,mBAAmB,GAAG,SAAS;CAKnC;AAED,4DAA4D;AAC5D,wBAAgB,wBAAwB,IAAI,kBAAkB,CAE7D"}
@@ -0,0 +1,26 @@
1
+ export class FieldInputRegistry {
2
+ #types = new Map();
3
+ #fields = new Map();
4
+ registerType(type, component) {
5
+ this.#types.set(type, component);
6
+ return () => {
7
+ if (this.#types.get(type) === component)
8
+ this.#types.delete(type);
9
+ };
10
+ }
11
+ registerField(objectRef, fieldName, component) {
12
+ const key = `${objectRef}.${fieldName}`;
13
+ this.#fields.set(key, component);
14
+ return () => {
15
+ if (this.#fields.get(key) === component)
16
+ this.#fields.delete(key);
17
+ };
18
+ }
19
+ resolve(objectRef, fieldName, type) {
20
+ return (this.#fields.get(`${objectRef}.${fieldName}`) ?? this.#types.get(type));
21
+ }
22
+ }
23
+ /** Create an isolated registry for one application root. */
24
+ export function createFieldInputRegistry() {
25
+ return new FieldInputRegistry();
26
+ }
@@ -0,0 +1,4 @@
1
+ import type { ObjectFormSource } from './types.js';
2
+ export declare function setObjectFormSource(source: ObjectFormSource): void;
3
+ export declare function tryGetObjectFormSource(): ObjectFormSource | undefined;
4
+ //# sourceMappingURL=object-form-source-context.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object-form-source-context.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/object-form-source-context.svelte.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAInD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAElE;AAED,wBAAgB,sBAAsB,IAAI,gBAAgB,GAAG,SAAS,CAErE"}
@@ -0,0 +1,8 @@
1
+ import { getContext, setContext } from 'svelte';
2
+ const OBJECT_FORM_SOURCE = Symbol('smrt-fields.object-form-source');
3
+ export function setObjectFormSource(source) {
4
+ setContext(OBJECT_FORM_SOURCE, source);
5
+ }
6
+ export function tryGetObjectFormSource() {
7
+ return getContext(OBJECT_FORM_SOURCE);
8
+ }
@@ -0,0 +1,18 @@
1
+ import type { ObjectFormCollectionDefinition, ObjectFormPolicyClient, ObjectFormResolvedSource, ObjectFormSource } from './types.js';
2
+ /** Validate browser-safe generated definitions before accepting them into an app registry. */
3
+ export declare function assertObjectFormCollectionDefinition(definition: unknown): asserts definition is ObjectFormCollectionDefinition;
4
+ /**
5
+ * Per-app registry that maps canonical object refs to generated web
6
+ * collection definitions and resolves their matching policy through the
7
+ * generated `resolveBatch` custom action. It deliberately accepts only
8
+ * structural types so Fields stays independent of smrt-web.
9
+ */
10
+ export declare class ObjectFormSourceRegistry implements ObjectFormSource {
11
+ private readonly policyClient;
12
+ private readonly definitions;
13
+ constructor(policyClient: ObjectFormPolicyClient);
14
+ register(definition: ObjectFormCollectionDefinition): () => void;
15
+ get(objectRef: string): ObjectFormCollectionDefinition | undefined;
16
+ load(objectRef: string): Promise<ObjectFormResolvedSource>;
17
+ }
18
+ //# sourceMappingURL=object-form-source.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object-form-source.svelte.d.ts","sourceRoot":"","sources":["../../src/svelte/object-form-source.svelte.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,8BAA8B,EAC9B,sBAAsB,EACtB,wBAAwB,EACxB,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AAqBpB,8FAA8F;AAC9F,wBAAgB,oCAAoC,CAClD,UAAU,EAAE,OAAO,GAClB,OAAO,CAAC,UAAU,IAAI,8BAA8B,CAqBtD;AA+BD;;;;;GAKG;AACH,qBAAa,wBAAyB,YAAW,gBAAgB;IAMnD,OAAO,CAAC,QAAQ,CAAC,YAAY;IALzC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAGxB;gBAEyB,YAAY,EAAE,sBAAsB;IAEjE,QAAQ,CAAC,UAAU,EAAE,8BAA8B,GAAG,MAAM,IAAI;IAWhE,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,8BAA8B,GAAG,SAAS;IAI5D,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC;CAkBjE"}
@@ -0,0 +1,99 @@
1
+ const WIRE_TYPES = new Set([
2
+ 'text',
3
+ 'integer',
4
+ 'decimal',
5
+ 'boolean',
6
+ 'datetime',
7
+ 'json',
8
+ 'foreignKey',
9
+ 'crossPackageRef',
10
+ ]);
11
+ function isRecord(value) {
12
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
13
+ }
14
+ function invalid(message) {
15
+ throw new Error(`Invalid ObjectForm source response: ${message}`);
16
+ }
17
+ /** Validate browser-safe generated definitions before accepting them into an app registry. */
18
+ export function assertObjectFormCollectionDefinition(definition) {
19
+ if (!isRecord(definition) ||
20
+ typeof definition.objectRef !== 'string' ||
21
+ !definition.objectRef.includes(':')) {
22
+ invalid('definition must have a canonical objectRef');
23
+ }
24
+ if (!isRecord(definition.fields)) {
25
+ invalid('definition fields must be an object');
26
+ }
27
+ for (const [name, field] of Object.entries(definition.fields)) {
28
+ if (!name ||
29
+ !isRecord(field) ||
30
+ !WIRE_TYPES.has(field.type) ||
31
+ (field.required !== undefined && typeof field.required !== 'boolean')) {
32
+ invalid(`field '${name}' is not a supported generated wire field`);
33
+ }
34
+ }
35
+ }
36
+ function assertResolvedPolicy(value, requestedObjectRef) {
37
+ if (!isRecord(value) ||
38
+ value.objectRef !== requestedObjectRef ||
39
+ !isRecord(value.fields)) {
40
+ invalid(`resolveBatch did not return policy for '${requestedObjectRef}'`);
41
+ }
42
+ for (const [name, field] of Object.entries(value.fields)) {
43
+ if (!isRecord(field) ||
44
+ field.fieldName !== name ||
45
+ !['basic', 'advanced', 'hidden'].includes(field.visibility) ||
46
+ typeof field.required !== 'boolean' ||
47
+ typeof field.hasDefault !== 'boolean' ||
48
+ (field.help !== null && typeof field.help !== 'string') ||
49
+ (field.label !== null && typeof field.label !== 'string') ||
50
+ (field.order !== null && typeof field.order !== 'number') ||
51
+ (field.group !== null && typeof field.group !== 'string') ||
52
+ typeof field.locked !== 'boolean') {
53
+ invalid(`policy field '${name}' is malformed`);
54
+ }
55
+ }
56
+ }
57
+ /**
58
+ * Per-app registry that maps canonical object refs to generated web
59
+ * collection definitions and resolves their matching policy through the
60
+ * generated `resolveBatch` custom action. It deliberately accepts only
61
+ * structural types so Fields stays independent of smrt-web.
62
+ */
63
+ export class ObjectFormSourceRegistry {
64
+ policyClient;
65
+ definitions = new Map();
66
+ constructor(policyClient) {
67
+ this.policyClient = policyClient;
68
+ }
69
+ register(definition) {
70
+ assertObjectFormCollectionDefinition(definition);
71
+ const objectRef = definition.objectRef;
72
+ this.definitions.set(objectRef, definition);
73
+ return () => {
74
+ if (this.definitions.get(objectRef) === definition) {
75
+ this.definitions.delete(objectRef);
76
+ }
77
+ };
78
+ }
79
+ get(objectRef) {
80
+ return this.definitions.get(objectRef);
81
+ }
82
+ async load(objectRef) {
83
+ const definition = this.definitions.get(objectRef);
84
+ if (!definition) {
85
+ throw new Error(`ObjectForm source has no definition for '${objectRef}'`);
86
+ }
87
+ // Generated custom action clients return Promise<any>; validate every
88
+ // boundary before a response drives accessible controls.
89
+ const response = await this.policyClient.resolveBatch({
90
+ objectRefs: [objectRef],
91
+ });
92
+ if (!isRecord(response) || !isRecord(response.policies)) {
93
+ invalid('resolveBatch response must contain a policies object');
94
+ }
95
+ const policy = response.policies[objectRef];
96
+ assertResolvedPolicy(policy, objectRef);
97
+ return { definition, policy };
98
+ }
99
+ }
@@ -0,0 +1,6 @@
1
+ /** Pure selection and ordering helpers used by ObjectForm and non-DOM tests. */
2
+ import type { ResolvedObjectFieldPolicy } from '../types.js';
3
+ import type { ObjectFormField, ObjectFormFieldDefinition } from './types.js';
4
+ /** Safe web definition × resolved policy intersection, ordered deterministically. */
5
+ export declare function resolveObjectFormFields(webFields: Readonly<Record<string, ObjectFormFieldDefinition>>, resolvedPolicy: ResolvedObjectFieldPolicy): ObjectFormField[];
6
+ //# sourceMappingURL=object-form.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object-form.d.ts","sourceRoot":"","sources":["../../src/svelte/object-form.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAsB7E,qFAAqF;AACrF,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC,EAC9D,cAAc,EAAE,yBAAyB,GACxC,eAAe,EAAE,CAwBnB"}
@@ -0,0 +1,38 @@
1
+ const SYSTEM_FIELD_NAMES = new Set([
2
+ 'id',
3
+ 'tenantId',
4
+ 'createdAt',
5
+ 'updatedAt',
6
+ 'createdBy',
7
+ 'updatedBy',
8
+ ]);
9
+ const FORMABLE_WIRE_TYPES = new Set([
10
+ 'text',
11
+ 'integer',
12
+ 'decimal',
13
+ 'boolean',
14
+ 'datetime',
15
+ 'json',
16
+ 'foreignKey',
17
+ 'crossPackageRef',
18
+ ]);
19
+ /** Safe web definition × resolved policy intersection, ordered deterministically. */
20
+ export function resolveObjectFormFields(webFields, resolvedPolicy) {
21
+ return Object.entries(webFields)
22
+ .filter(([name, definition]) => !SYSTEM_FIELD_NAMES.has(name) &&
23
+ !name.startsWith('_smrt_') &&
24
+ FORMABLE_WIRE_TYPES.has(definition.type) &&
25
+ resolvedPolicy.fields[name] !== undefined)
26
+ .map(([name, definition]) => {
27
+ const policyField = resolvedPolicy.fields[name];
28
+ return {
29
+ name,
30
+ definition,
31
+ group: policyField.group ?? definition.ui?.group ?? null,
32
+ order: policyField.order ?? definition.ui?.order ?? null,
33
+ };
34
+ })
35
+ .sort((left, right) => (left.order ?? Number.MAX_SAFE_INTEGER) -
36
+ (right.order ?? Number.MAX_SAFE_INTEGER) ||
37
+ left.name.localeCompare(right.name));
38
+ }