@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.
- package/AGENTS.md +58 -12
- package/README.md +90 -2
- package/dist/__smrt-register__.d.ts +2 -0
- package/dist/__smrt-register__.d.ts.map +1 -0
- package/dist/cache.d.ts +18 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/collections/FieldPolicyCollection.d.ts +95 -0
- package/dist/collections/FieldPolicyCollection.d.ts.map +1 -0
- package/dist/field-definitions.d.ts +77 -0
- package/dist/field-definitions.d.ts.map +1 -0
- package/dist/field-policy-resolver.d.ts +46 -0
- package/dist/field-policy-resolver.d.ts.map +1 -0
- package/dist/index.d.ts +9 -532
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +752 -55
- package/dist/index.js.map +1 -1
- package/dist/manifest.json +45 -3
- package/dist/models/FieldPolicy.d.ts +163 -0
- package/dist/models/FieldPolicy.d.ts.map +1 -0
- package/dist/permissions.d.ts +9 -0
- package/dist/permissions.d.ts.map +1 -0
- package/dist/playground.d.ts +2 -0
- package/dist/playground.d.ts.map +1 -0
- package/dist/playground.js +39 -0
- package/dist/playground.js.map +1 -0
- package/dist/settings-catalog.d.ts +73 -0
- package/dist/settings-catalog.d.ts.map +1 -0
- package/dist/smrt-knowledge.json +50 -7
- package/dist/svelte/__tests__/FieldPolicyControlPanel.test.js +223 -0
- package/dist/svelte/__tests__/FieldPolicyGear.test.js +503 -0
- package/dist/svelte/__tests__/FormHelp.test.js +138 -0
- package/dist/svelte/__tests__/ModeUX.test.js +109 -0
- package/dist/svelte/__tests__/ObjectForm.test.js +556 -0
- package/dist/svelte/__tests__/ObjectFormGeneratedApi.integration.test.js +436 -0
- package/dist/svelte/__tests__/PolicyField.test.js +373 -0
- package/dist/svelte/__tests__/fixtures/AdvancedFieldsFixture.svelte +30 -0
- package/dist/svelte/__tests__/fixtures/AdvancedFieldsFixture.svelte.d.ts +9 -0
- package/dist/svelte/__tests__/fixtures/AdvancedFieldsFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/DomPrefillFixture.svelte +33 -0
- package/dist/svelte/__tests__/fixtures/DomPrefillFixture.svelte.d.ts +10 -0
- package/dist/svelte/__tests__/fixtures/DomPrefillFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/FormHelpFixture.svelte +19 -0
- package/dist/svelte/__tests__/fixtures/FormHelpFixture.svelte.d.ts +10 -0
- package/dist/svelte/__tests__/fixtures/FormHelpFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/GeneratedApiGearFixture.svelte +18 -0
- package/dist/svelte/__tests__/fixtures/GeneratedApiGearFixture.svelte.d.ts +11 -0
- package/dist/svelte/__tests__/fixtures/GeneratedApiGearFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/GracefulDegradeFixture.svelte +11 -0
- package/dist/svelte/__tests__/fixtures/GracefulDegradeFixture.svelte.d.ts +19 -0
- package/dist/svelte/__tests__/fixtures/GracefulDegradeFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ModeSwitchFixture.svelte +18 -0
- package/dist/svelte/__tests__/fixtures/ModeSwitchFixture.svelte.d.ts +8 -0
- package/dist/svelte/__tests__/fixtures/ModeSwitchFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/NoIdFixture.svelte +24 -0
- package/dist/svelte/__tests__/fixtures/NoIdFixture.svelte.d.ts +13 -0
- package/dist/svelte/__tests__/fixtures/NoIdFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormActionsFixture.svelte +20 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormActionsFixture.svelte.d.ts +11 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormActionsFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormFixture.svelte +17 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormFixture.svelte.d.ts +10 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormRegistryFixture.svelte +25 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormRegistryFixture.svelte.d.ts +10 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormRegistryFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSnippetFixture.svelte +34 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSnippetFixture.svelte.d.ts +10 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSnippetFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceFixture.svelte +29 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceFixture.svelte.d.ts +11 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceSnippetFixture.svelte +33 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceSnippetFixture.svelte.d.ts +9 -0
- package/dist/svelte/__tests__/fixtures/ObjectFormSourceSnippetFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/PolicyDataTableFixture.svelte +40 -0
- package/dist/svelte/__tests__/fixtures/PolicyDataTableFixture.svelte.d.ts +8 -0
- package/dist/svelte/__tests__/fixtures/PolicyDataTableFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/PrefillFixture.svelte +26 -0
- package/dist/svelte/__tests__/fixtures/PrefillFixture.svelte.d.ts +13 -0
- package/dist/svelte/__tests__/fixtures/PrefillFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ProviderFieldFixture.svelte +39 -0
- package/dist/svelte/__tests__/fixtures/ProviderFieldFixture.svelte.d.ts +17 -0
- package/dist/svelte/__tests__/fixtures/ProviderFieldFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/RegistryInput.svelte +15 -0
- package/dist/svelte/__tests__/fixtures/RegistryInput.svelte.d.ts +5 -0
- package/dist/svelte/__tests__/fixtures/RegistryInput.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/RevealPrefillFixture.svelte +29 -0
- package/dist/svelte/__tests__/fixtures/RevealPrefillFixture.svelte.d.ts +14 -0
- package/dist/svelte/__tests__/fixtures/RevealPrefillFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/SettingsCatalogStub.svelte +24 -0
- package/dist/svelte/__tests__/fixtures/SettingsCatalogStub.svelte.d.ts +14 -0
- package/dist/svelte/__tests__/fixtures/SettingsCatalogStub.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/SnippetFixture.svelte +28 -0
- package/dist/svelte/__tests__/fixtures/SnippetFixture.svelte.d.ts +13 -0
- package/dist/svelte/__tests__/fixtures/SnippetFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/ToggleModeButton.svelte +14 -0
- package/dist/svelte/__tests__/fixtures/ToggleModeButton.svelte.d.ts +19 -0
- package/dist/svelte/__tests__/fixtures/ToggleModeButton.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/fixtures/TooltipFixture.svelte +25 -0
- package/dist/svelte/__tests__/fixtures/TooltipFixture.svelte.d.ts +14 -0
- package/dist/svelte/__tests__/fixtures/TooltipFixture.svelte.d.ts.map +1 -0
- package/dist/svelte/__tests__/settings-catalog.test.js +161 -0
- package/dist/svelte/components/AdvancedFields.svelte +49 -0
- package/dist/svelte/components/AdvancedFields.svelte.d.ts +17 -0
- package/dist/svelte/components/AdvancedFields.svelte.d.ts.map +1 -0
- package/dist/svelte/components/FieldInput.svelte +159 -0
- package/dist/svelte/components/FieldInput.svelte.d.ts +5 -0
- package/dist/svelte/components/FieldInput.svelte.d.ts.map +1 -0
- package/dist/svelte/components/FieldPolicyControlPanel.svelte +261 -0
- package/dist/svelte/components/FieldPolicyControlPanel.svelte.d.ts +26 -0
- package/dist/svelte/components/FieldPolicyControlPanel.svelte.d.ts.map +1 -0
- package/dist/svelte/components/FieldPolicyEditor.svelte +417 -0
- package/dist/svelte/components/FieldPolicyEditor.svelte.d.ts +18 -0
- package/dist/svelte/components/FieldPolicyEditor.svelte.d.ts.map +1 -0
- package/dist/svelte/components/FieldPolicyGearButton.svelte +17 -0
- package/dist/svelte/components/FieldPolicyGearButton.svelte.d.ts +8 -0
- package/dist/svelte/components/FieldPolicyGearButton.svelte.d.ts.map +1 -0
- package/dist/svelte/components/FieldPolicyGearProvider.svelte +135 -0
- package/dist/svelte/components/FieldPolicyGearProvider.svelte.d.ts +17 -0
- package/dist/svelte/components/FieldPolicyGearProvider.svelte.d.ts.map +1 -0
- package/dist/svelte/components/FieldPolicyProvider.svelte +89 -0
- package/dist/svelte/components/FieldPolicyProvider.svelte.d.ts +35 -0
- package/dist/svelte/components/FieldPolicyProvider.svelte.d.ts.map +1 -0
- package/dist/svelte/components/FormHelp.svelte +157 -0
- package/dist/svelte/components/FormHelp.svelte.d.ts +15 -0
- package/dist/svelte/components/FormHelp.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ModeSwitch.svelte +47 -0
- package/dist/svelte/components/ModeSwitch.svelte.d.ts +10 -0
- package/dist/svelte/components/ModeSwitch.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ObjectForm.svelte +351 -0
- package/dist/svelte/components/ObjectForm.svelte.d.ts +40 -0
- package/dist/svelte/components/ObjectForm.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ObjectFormSourceProvider.svelte +18 -0
- package/dist/svelte/components/ObjectFormSourceProvider.svelte.d.ts +11 -0
- package/dist/svelte/components/ObjectFormSourceProvider.svelte.d.ts.map +1 -0
- package/dist/svelte/components/PolicyField.svelte +338 -0
- package/dist/svelte/components/PolicyField.svelte.d.ts +80 -0
- package/dist/svelte/components/PolicyField.svelte.d.ts.map +1 -0
- package/dist/svelte/context.svelte.d.ts +54 -0
- package/dist/svelte/context.svelte.d.ts.map +1 -0
- package/dist/svelte/context.svelte.js +55 -0
- package/dist/svelte/data-table.d.ts +17 -0
- package/dist/svelte/data-table.d.ts.map +1 -0
- package/dist/svelte/data-table.js +19 -0
- package/dist/svelte/field-policy-editor.d.ts +81 -0
- package/dist/svelte/field-policy-editor.d.ts.map +1 -0
- package/dist/svelte/field-policy-editor.js +120 -0
- package/dist/svelte/gear-context.svelte.d.ts +14 -0
- package/dist/svelte/gear-context.svelte.d.ts.map +1 -0
- package/dist/svelte/gear-context.svelte.js +15 -0
- package/dist/svelte/index.d.ts +58 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +38 -0
- package/dist/svelte/input-registry.d.ts +21 -0
- package/dist/svelte/input-registry.d.ts.map +1 -0
- package/dist/svelte/input-registry.js +26 -0
- package/dist/svelte/object-form-source-context.svelte.d.ts +4 -0
- package/dist/svelte/object-form-source-context.svelte.d.ts.map +1 -0
- package/dist/svelte/object-form-source-context.svelte.js +8 -0
- package/dist/svelte/object-form-source.svelte.d.ts +18 -0
- package/dist/svelte/object-form-source.svelte.d.ts.map +1 -0
- package/dist/svelte/object-form-source.svelte.js +99 -0
- package/dist/svelte/object-form.d.ts +6 -0
- package/dist/svelte/object-form.d.ts.map +1 -0
- package/dist/svelte/object-form.js +38 -0
- package/dist/svelte/playground/FieldPolicyFormPreview.svelte +212 -0
- package/dist/svelte/playground/FieldPolicyFormPreview.svelte.d.ts +4 -0
- package/dist/svelte/playground/FieldPolicyFormPreview.svelte.d.ts.map +1 -0
- package/dist/svelte/playground/ObjectFormPreview.svelte +129 -0
- package/dist/svelte/playground/ObjectFormPreview.svelte.d.ts +4 -0
- package/dist/svelte/playground/ObjectFormPreview.svelte.d.ts.map +1 -0
- package/dist/svelte/playground.d.ts +20 -0
- package/dist/svelte/playground.d.ts.map +1 -0
- package/dist/svelte/playground.js +38 -0
- package/dist/svelte/settings-catalog.d.ts +54 -0
- package/dist/svelte/settings-catalog.d.ts.map +1 -0
- package/dist/svelte/settings-catalog.js +116 -0
- package/dist/svelte/types.d.ts +101 -0
- package/dist/svelte/types.d.ts.map +1 -0
- package/dist/svelte/types.js +4 -0
- package/dist/types.d.ts +276 -203
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js.map +1 -1
- package/package.json +33 -8
package/AGENTS.md
CHANGED
|
@@ -36,9 +36,11 @@ per-field `{defaultValue, visibility, help, label, order, locked}` for any
|
|
|
36
36
|
2. App rows — `scopeType: 'app'`, `tenantId`/`userId` null
|
|
37
37
|
3. Tenant rows — hierarchy walk root → leaf via an injected
|
|
38
38
|
`tenantHierarchyLoader` (smrt-features shape); the default loader
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
uses `@happyvertical/smrt-users`' `TenantCollection`; an injected loader
|
|
40
|
+
may return no provider (or no chain for a tenant), which falls back to a
|
|
41
|
+
flat single-tenant chain. `smrt-users` itself is a required Fields runtime
|
|
42
|
+
dependency for policy authorization, not an optional hierarchy dependency.
|
|
43
|
+
A node that breaks permission
|
|
42
44
|
inheritance discards every earlier tenant contribution (chain-structural),
|
|
43
45
|
so only the suffix from the LAST break participates — in merging AND in
|
|
44
46
|
the explained layers, which therefore replay to the merged result
|
|
@@ -75,9 +77,11 @@ per-field `{defaultValue, visibility, help, label, order, locked}` for any
|
|
|
75
77
|
- **Write-time org checks reuse the resolver**: the required-demotion default
|
|
76
78
|
and the user-write lock are computed by `resolveFieldPolicy` over the org
|
|
77
79
|
tiers (default hierarchy loader), so cascading ancestor-tenant defaults and
|
|
78
|
-
locks are honored at save time too. On updates the
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
locks are honored at save time too. On updates the persisted row is excluded
|
|
81
|
+
from projected lower-layer resolution, so clearing the row's only default
|
|
82
|
+
while demoting a required field is rejected before mutation; that projected
|
|
83
|
+
lookup bypasses the shared cache. The resolver-side safety net remains
|
|
84
|
+
authoritative when a different row is later deleted.
|
|
81
85
|
- **Isolation — a MISSING identity component DENIES, it never skips.** This
|
|
82
86
|
is the package rule; both the write guard
|
|
83
87
|
(`FieldPolicy.assertScopeOwnedByAmbientContext`) and the read guard
|
|
@@ -88,12 +92,13 @@ per-field `{defaultValue, visibility, help, label, order, locked}` for any
|
|
|
88
92
|
`withTenant({ tenantId })`) may not touch the user tier at all. Skipping
|
|
89
93
|
that check instead of denying it was a live ownership bypass: user rows are
|
|
90
94
|
`tenantId: null` by design, so nothing else contains such a write. App-scope
|
|
91
|
-
writes inside a tenant context require super-admin bypass.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
writes inside a tenant context require super-admin bypass. `fields.policy.manage`
|
|
96
|
+
authorizes app/tenant policy mutations; `fields.policy.personalize` authorizes
|
|
97
|
+
only the caller's user tier (default-seeded for built-in roles). With NO ambient
|
|
98
|
+
identity at all (tenancy ALS never entered), policy writes/deletes fail closed;
|
|
99
|
+
trusted system and super-admin contexts retain their explicit bypasses.
|
|
100
|
+
Context-LESS *reads* stay allowed because `resolveFieldPolicy` is a trusted
|
|
101
|
+
server-side API. `save()`/`delete()`
|
|
97
102
|
on an existing row additionally authorize against the row's PERSISTED
|
|
98
103
|
scope, looked up by primary key AND — because a generated create always
|
|
99
104
|
mints a fresh UUID while the `conflictColumns` upsert still replaces the
|
|
@@ -171,6 +176,47 @@ per-field `{defaultValue, visibility, help, label, order, locked}` for any
|
|
|
171
176
|
(`_smrt_field_policies`), and both are pinned in
|
|
172
177
|
`generated-surfaces.test.ts`.
|
|
173
178
|
|
|
179
|
+
## Svelte generated forms (#2049)
|
|
180
|
+
|
|
181
|
+
- `ObjectForm` accepts direct generated `fields` plus a resolved `policy` for
|
|
182
|
+
SSR and explicit hosts, or accepts only `objectRef` beneath an
|
|
183
|
+
`ObjectFormSourceProvider`. `ObjectFormSourceRegistry` is per app and maps
|
|
184
|
+
canonical refs to generated web collection definitions before calling the
|
|
185
|
+
generated `resolveBatch` custom action. It uses structural types only: this
|
|
186
|
+
package must never import `smrt-web`.
|
|
187
|
+
- Generated custom-action clients resolve `Promise<any>`; validate their
|
|
188
|
+
`policies[objectRef]` response at the registry boundary and fail closed on a
|
|
189
|
+
missing/mismatched definition or policy. The component renders an accessible
|
|
190
|
+
loading state and alert rather than a partial form.
|
|
191
|
+
- Browser manifest types are `text`, `integer`, `decimal`, `boolean`,
|
|
192
|
+
`datetime`, `json`, `foreignKey`, and `crossPackageRef`; there is no `select`
|
|
193
|
+
wire type. Apps use the per-app `FieldInputRegistry.registerField` seam for
|
|
194
|
+
select-like widgets. Reference fields intentionally default to identifier
|
|
195
|
+
inputs unless an app supplies a chooser.
|
|
196
|
+
- `policyToVisibleColumnIds(policy, columns)` feeds smrt-ui `DataTable`'s
|
|
197
|
+
`visibleColumnIds`; it filters policy-hidden mapped fields, preserves unmapped
|
|
198
|
+
computed/action columns, and cannot reveal a static `column.hidden` column.
|
|
199
|
+
|
|
200
|
+
## Defaults control panel (#2050)
|
|
201
|
+
|
|
202
|
+
- `buildFieldPolicySettingsCatalog()` is the server-side, URL/GET-driven
|
|
203
|
+
catalog builder. It structurally targets `SettingsCatalog`, but this package
|
|
204
|
+
must not import `smrt-svelte`; hosts inject `SettingsCatalog` into
|
|
205
|
+
`FieldPolicyControlPanel` and retain their own route and transport adapters.
|
|
206
|
+
- `policyAudit` is the only routed organization roll-up. It requires
|
|
207
|
+
`fields.policy.manage`, returns only the caller tenant's editable rows and
|
|
208
|
+
read-only app summaries, and represents other users strictly as per-field
|
|
209
|
+
counts. It resolves only requested page refs; never pre-resolve the catalog.
|
|
210
|
+
- Display code/app/org values by replaying the explained resolver layers, not
|
|
211
|
+
by independently calculating precedence. Reset and drift prune are ordinary
|
|
212
|
+
model deletes, so existing scope/permission validation remains authoritative.
|
|
213
|
+
The panel asks for an explicit confirmation before either destructive action;
|
|
214
|
+
SSR hosts can inject that confirmation decision instead of relying on
|
|
215
|
+
`window.confirm`.
|
|
216
|
+
- `fieldPolicyControlPanelNavItem()` is a structural AdminShell tenant-nav
|
|
217
|
+
seam. It never imports `smrt-svelte` or `smrt-web`; the host supplies the
|
|
218
|
+
returned entry and must enforce its real route permission server-side.
|
|
219
|
+
|
|
174
220
|
## Related
|
|
175
221
|
|
|
176
222
|
- `@happyvertical/smrt-prompts` / `smrt-languages` / `smrt-features` — the
|
package/README.md
CHANGED
|
@@ -39,10 +39,15 @@ const explained = await resolveFieldPolicyExplained(
|
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
Resolution layers (low → high): code seed → app rows → tenant rows
|
|
42
|
-
(hierarchy walk via
|
|
43
|
-
|
|
42
|
+
(hierarchy walk via the users tenant loader, or a flat fallback when an
|
|
43
|
+
injected hierarchy provider cannot resolve the tenant) → user rows. A NULL column inherits
|
|
44
44
|
from the lower layer; resetting a customization is a row delete.
|
|
45
45
|
|
|
46
|
+
`@happyvertical/smrt-users` is a required runtime dependency: Field Policy
|
|
47
|
+
uses its permission catalog and operation guard for every write and gear
|
|
48
|
+
action. The hierarchy fallback concerns tenant ancestry only; it is not a
|
|
49
|
+
users-authorization fallback.
|
|
50
|
+
|
|
46
51
|
Writes are validated against the live `ObjectRegistry`: unknown
|
|
47
52
|
objects/fields are rejected, defaults are type-checked, and defaults on
|
|
48
53
|
`transient`/`sensitive`/`readPermission`-gated fields are refused. Required
|
|
@@ -50,3 +55,86 @@ fields can only be demoted from `basic` when a usable default resolves —
|
|
|
50
55
|
and the resolver re-enforces that invariant at read time.
|
|
51
56
|
|
|
52
57
|
See `AGENTS.md` for the full architecture notes.
|
|
58
|
+
|
|
59
|
+
## Svelte ObjectForm
|
|
60
|
+
|
|
61
|
+
`@happyvertical/smrt-fields/svelte` provides provider-free generated forms.
|
|
62
|
+
Pass only the generated browser field definitions and the matching resolved
|
|
63
|
+
policy; `ObjectForm` renders their safe intersection, honors policy visibility
|
|
64
|
+
and ordering, and keeps form state transport-neutral.
|
|
65
|
+
|
|
66
|
+
```svelte
|
|
67
|
+
<script lang="ts">
|
|
68
|
+
import { ObjectForm, createFieldInputRegistry } from '@happyvertical/smrt-fields/svelte';
|
|
69
|
+
|
|
70
|
+
const inputRegistry = createFieldInputRegistry();
|
|
71
|
+
// inputRegistry.registerField(objectRef, 'body', RichTextInput);
|
|
72
|
+
</script>
|
|
73
|
+
|
|
74
|
+
<ObjectForm {objectRef} fields={collectionDefinition.fields} {policy}
|
|
75
|
+
bind:value={record} {inputRegistry} />
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Pass an `actions` snippet to place host controls inside the owned native form.
|
|
79
|
+
The snippet renders after ObjectForm's policy-ordered fields, so a regular
|
|
80
|
+
submit button keeps native Enter/click submission and ObjectForm's validation
|
|
81
|
+
and `onsubmit` handling without querying the DOM.
|
|
82
|
+
|
|
83
|
+
```svelte
|
|
84
|
+
<ObjectForm {objectRef} fields={collectionDefinition.fields} {policy}
|
|
85
|
+
bind:value={record} onsubmit={save}>
|
|
86
|
+
{#snippet actions()}
|
|
87
|
+
<button type="submit">Save</button>
|
|
88
|
+
{/snippet}
|
|
89
|
+
</ObjectForm>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
An app can register all of its generated collection definitions once and put
|
|
93
|
+
the `resolveBatch` custom-action client behind an `ObjectFormSourceProvider`.
|
|
94
|
+
Then forms need only their canonical object reference; the registry validates
|
|
95
|
+
the generated definition and the untyped custom-action response before it is
|
|
96
|
+
rendered, failing closed with an accessible error state on a missing or
|
|
97
|
+
mismatched response.
|
|
98
|
+
|
|
99
|
+
```svelte
|
|
100
|
+
<script lang="ts">
|
|
101
|
+
import {
|
|
102
|
+
ObjectForm,
|
|
103
|
+
ObjectFormSourceProvider,
|
|
104
|
+
ObjectFormSourceRegistry,
|
|
105
|
+
} from '@happyvertical/smrt-fields/svelte';
|
|
106
|
+
|
|
107
|
+
const source = new ObjectFormSourceRegistry(fieldPoliciesClient);
|
|
108
|
+
for (const definition of Object.values(collectionDefinitions)) source.register(definition);
|
|
109
|
+
</script>
|
|
110
|
+
|
|
111
|
+
<ObjectFormSourceProvider {source}>
|
|
112
|
+
<ObjectForm objectRef="@happyvertical/smrt-products:Product" bind:value={record} />
|
|
113
|
+
</ObjectFormSourceProvider>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The built-ins support text, integer, decimal, boolean, datetime, JSON, and
|
|
117
|
+
reference identifiers. `FieldInputRegistry` is per app: a field-specific
|
|
118
|
+
renderer takes precedence over a wire-type renderer. SMRT has no `select` wire
|
|
119
|
+
type: keep the persisted wire type (normally `text`) and register a
|
|
120
|
+
field-specific select-like renderer with `registerField(objectRef, fieldName,
|
|
121
|
+
component)`. Reference fields deliberately remain provider-free identifier
|
|
122
|
+
inputs unless an app registers its own chooser. `policyToVisibleColumnIds`
|
|
123
|
+
adapts the same resolved policy to `DataTable` without hiding unmapped action or
|
|
124
|
+
computed columns; static `column.hidden` remains authoritative.
|
|
125
|
+
|
|
126
|
+
When a mounted create form starts another record, replace the bound record with
|
|
127
|
+
an empty object or change `createSessionKey`; both begin a new default-prefill
|
|
128
|
+
session without reapplying defaults after an in-form user clear.
|
|
129
|
+
|
|
130
|
+
## Policy settings gear
|
|
131
|
+
|
|
132
|
+
`FieldPolicyGearProvider` makes the context-derived `editor-state` action
|
|
133
|
+
available to any policy-aware form without choosing a client transport. Pass an
|
|
134
|
+
adapter around the generated collection client's `getEditorState`, `create`,
|
|
135
|
+
`update`, and `delete` calls; it must not accept tenant or user identifiers.
|
|
136
|
+
Use `FieldPolicyGearButton` where the form wants its affordance, or set
|
|
137
|
+
`showPolicyGear` on `ObjectForm`. `registerFieldPolicyFocusTool(shell,
|
|
138
|
+
objectRef, tool)` is a structural AdminShell seam: it registers the required
|
|
139
|
+
`{ type: 'object-form', id: objectRef }` subject and returns the shell's
|
|
140
|
+
disposer without making Fields depend on `smrt-svelte`.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"__smrt-register__.d.ts","sourceRoot":"","sources":["../src/__smrt-register__.ts"],"names":[],"mappings":""}
|
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { DatabaseInterface } from '@happyvertical/sql';
|
|
2
|
+
import { ExplainedObjectFieldPolicy } from './types.js';
|
|
3
|
+
export declare function getFieldPolicyCacheTtlMs(): number;
|
|
4
|
+
export declare function getCachedFieldPolicy(objectRef: string, tenantId: string | null | undefined, userId: string | null | undefined, db: DatabaseInterface | unknown, hierarchyLoader?: unknown): ExplainedObjectFieldPolicy | null;
|
|
5
|
+
export declare function setCachedFieldPolicy(objectRef: string, tenantId: string | null | undefined, userId: string | null | undefined, db: DatabaseInterface | unknown, value: ExplainedObjectFieldPolicy, hierarchyLoader?: unknown): void;
|
|
6
|
+
/**
|
|
7
|
+
* Drop every cached resolution for `(db, objectRef)`.
|
|
8
|
+
*
|
|
9
|
+
* Deliberately coarser than the prompts precedent (which deletes a single
|
|
10
|
+
* `(key, tenantId)` entry when the tenant is known): tenant HIERARCHY makes a
|
|
11
|
+
* parent-tenant row change affect every descendant tenant's resolution, and a
|
|
12
|
+
* lock or app-row change affects user-tier entries too, so precise
|
|
13
|
+
* invalidation would have to know the whole tenant tree. Per-objectRef prefix
|
|
14
|
+
* invalidation is always correct and the 30s TTL keeps the cost bounded.
|
|
15
|
+
*/
|
|
16
|
+
export declare function invalidateFieldPolicyCache(objectRef: string, db: DatabaseInterface | unknown): void;
|
|
17
|
+
export declare function clearFieldPolicyCache(): void;
|
|
18
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AA2F7D,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACjC,EAAE,EAAE,iBAAiB,GAAG,OAAO,EAC/B,eAAe,CAAC,EAAE,OAAO,GACxB,0BAA0B,GAAG,IAAI,CAoBnC;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACjC,EAAE,EAAE,iBAAiB,GAAG,OAAO,EAC/B,KAAK,EAAE,0BAA0B,EACjC,eAAe,CAAC,EAAE,OAAO,GACxB,IAAI,CAQN;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EACjB,EAAE,EAAE,iBAAiB,GAAG,OAAO,GAC9B,IAAI,CAON;AAED,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { SmrtCollection } from '@happyvertical/smrt-core';
|
|
2
|
+
import { FieldPolicy } from '../models/FieldPolicy.js';
|
|
3
|
+
import { FieldPolicyAuditSnapshot, FieldPolicyBatchResult, FieldPolicyEditorStateResult } from '../types.js';
|
|
4
|
+
/** Public cap shared by the server catalog and browser adapter. */
|
|
5
|
+
export declare const MAX_FIELD_POLICY_AUDIT_OBJECT_REFS = 100;
|
|
6
|
+
/** Count queries are projected, so they can cover a page plus an off-page selection. */
|
|
7
|
+
export declare const MAX_FIELD_POLICY_AUDIT_COUNT_REFS: number;
|
|
8
|
+
/**
|
|
9
|
+
* Collection surface for {@link FieldPolicy} rows plus the batch resolve
|
|
10
|
+
* action consumed by client bootstrapping (#2048).
|
|
11
|
+
*
|
|
12
|
+
* `resolveBatch` is a custom collection-scoped action (NOT a system route —
|
|
13
|
+
* core's generated system trio is closed): the generated route parses the
|
|
14
|
+
* body, calls the method on the app-configured collection instance (which
|
|
15
|
+
* carries the app database), and serializes the plain result.
|
|
16
|
+
*
|
|
17
|
+
* Exposure note: a decorated collection's config becomes the RUNTIME registry
|
|
18
|
+
* authority for its item class (core merges the collection registration onto
|
|
19
|
+
* the item slot), while build-time generation reads each manifest object's
|
|
20
|
+
* own config. This config therefore mirrors FieldPolicy's API posture —
|
|
21
|
+
* writes open plus the batch action, reads CLOSED (generated list/get would
|
|
22
|
+
* enumerate every tenant's/user's rows) — and closes the runtime CLI/MCP
|
|
23
|
+
* surfaces entirely (the ContentContributions precedent; the cli↔api
|
|
24
|
+
* coherence gate does not admit standard CRUD entries on a collection's
|
|
25
|
+
* `cli.include`). Keep the api include lists in lockstep with FieldPolicy's.
|
|
26
|
+
*/
|
|
27
|
+
export declare class FieldPolicyCollection extends SmrtCollection<FieldPolicy> {
|
|
28
|
+
static readonly _itemClass: typeof FieldPolicy;
|
|
29
|
+
/**
|
|
30
|
+
* Permission-gated, tenant-scoped audit read for the defaults control
|
|
31
|
+
* panel. It returns editable own-tenant rows, read-only app summaries,
|
|
32
|
+
* projected user override counts, and identity-only manifest drift rows.
|
|
33
|
+
*/
|
|
34
|
+
policyAudit(options?: {
|
|
35
|
+
objectRefs?: string[];
|
|
36
|
+
countObjectRefs?: string[];
|
|
37
|
+
/** Capability-only bootstrap for catalog builders before page selection. */
|
|
38
|
+
summaryOnly?: boolean;
|
|
39
|
+
/** Return row/count roll-ups without resolving field-policy layers. */
|
|
40
|
+
countsOnly?: boolean;
|
|
41
|
+
/** Return the first bounded page of manifest drift candidates. */
|
|
42
|
+
includeDrift?: boolean;
|
|
43
|
+
}): Promise<FieldPolicyAuditSnapshot>;
|
|
44
|
+
private resolveAuditPolicies;
|
|
45
|
+
/** All app-scope rows for an object, keyed by field name. */
|
|
46
|
+
getAppRows(objectRef: string): Promise<Map<string, FieldPolicy>>;
|
|
47
|
+
/**
|
|
48
|
+
* All tenant-scope rows for an object across a tenant chain, keyed
|
|
49
|
+
* `tenantId → fieldName → row`.
|
|
50
|
+
*/
|
|
51
|
+
getTenantRows(objectRef: string, tenantIds: string[]): Promise<Map<string, Map<string, FieldPolicy>>>;
|
|
52
|
+
/** All user-scope rows for an object and user, keyed by field name. */
|
|
53
|
+
getUserRows(objectRef: string, userId: string): Promise<Map<string, FieldPolicy>>;
|
|
54
|
+
/**
|
|
55
|
+
* Resolve merged field policy for a set of objectRefs for the CURRENT
|
|
56
|
+
* caller, gated for public consumption.
|
|
57
|
+
*
|
|
58
|
+
* Caller identity comes exclusively from the ambient tenant context
|
|
59
|
+
* (established by the app's auth hook, e.g. smrt-users' session context) —
|
|
60
|
+
* the request body cannot select another tenant or user (fail closed).
|
|
61
|
+
* Server-side consumers wanting explicit identities call
|
|
62
|
+
* `resolveFieldPolicy()` directly instead.
|
|
63
|
+
*
|
|
64
|
+
* Field gating mirrors the REST serializer's derivation (`sensitive` /
|
|
65
|
+
* `readPermission` read from both the top level and `_meta`): sensitive and
|
|
66
|
+
* read-permission-gated fields are ABSENT from the response for every
|
|
67
|
+
* caller (the generated action route cannot convey per-caller grants to
|
|
68
|
+
* this method, so gated fields fail closed), and transient fields are
|
|
69
|
+
* stripped for parity with generated client field definitions.
|
|
70
|
+
*/
|
|
71
|
+
resolveBatch(options?: {
|
|
72
|
+
objectRefs?: string[];
|
|
73
|
+
}): Promise<FieldPolicyBatchResult>;
|
|
74
|
+
/**
|
|
75
|
+
* Context-derived bootstrap data for the policy gear. This is deliberately
|
|
76
|
+
* a collection action instead of reopening list/get: a caller can inspect
|
|
77
|
+
* only their safe effective policy and rows/layers they are permitted to
|
|
78
|
+
* edit, never arbitrary tenant or user policy rows.
|
|
79
|
+
*/
|
|
80
|
+
getEditorState(options?: {
|
|
81
|
+
objectRef?: string;
|
|
82
|
+
}): Promise<FieldPolicyEditorStateResult>;
|
|
83
|
+
/**
|
|
84
|
+
* Compute the non-disclosing fallback signal used only by personal drafts.
|
|
85
|
+
* Passing no user id resolves exactly code/app/tenant precedence, including
|
|
86
|
+
* the real tenant hierarchy, while keeping every lower-layer value server
|
|
87
|
+
* side. The public map is limited to fields already admitted by the editor
|
|
88
|
+
* response's security rail.
|
|
89
|
+
*/
|
|
90
|
+
private getPersonalLowerDefaultUsability;
|
|
91
|
+
private gateResolvedForPublicResponse;
|
|
92
|
+
private gateExplainedForEditorResponse;
|
|
93
|
+
private toEditorRows;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=FieldPolicyCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FieldPolicyCollection.d.ts","sourceRoot":"","sources":["../../src/collections/FieldPolicyCollection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAQ,MAAM,0BAA0B,CAAC;AAiBhE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAKvD,OAAO,KAAK,EAGV,wBAAwB,EACxB,sBAAsB,EAItB,4BAA4B,EAE7B,MAAM,aAAa,CAAC;AAIrB,mEAAmE;AACnE,eAAO,MAAM,kCAAkC,MAAwB,CAAC;AACxE,wFAAwF;AACxF,eAAO,MAAM,iCAAiC,QAA4B,CAAC;AAE3E;;;;;;;;;;;;;;;;;;GAkBG;AAQH,qBAoCa,qBAAsB,SAAQ,cAAc,CAAC,WAAW,CAAC;IACpE,MAAM,CAAC,QAAQ,CAAC,UAAU,qBAAe;IAEzC;;;;OAIG;IACG,WAAW,CACf,OAAO,GAAE;QACP,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;QAC3B,4EAA4E;QAC5E,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,uEAAuE;QACvE,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,kEAAkE;QAClE,YAAY,CAAC,EAAE,OAAO,CAAC;KACnB,GACL,OAAO,CAAC,wBAAwB,CAAC;YA+NtB,oBAAoB;IA6BlC,6DAA6D;IACvD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAWtE;;;OAGG;IACG,aAAa,CACjB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAuBjD,uEAAuE;IACjE,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAWpC;;;;;;;;;;;;;;;;OAgBG;IACG,YAAY,CAChB,OAAO,GAAE;QAAE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;KAAO,GACtC,OAAO,CAAC,sBAAsB,CAAC;IAuClC;;;;;OAKG;IACG,cAAc,CAClB,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,4BAA4B,CAAC;IAsGxC;;;;;;OAMG;YACW,gCAAgC;YAuBhC,6BAA6B;YAwB7B,8BAA8B;IAiC5C,OAAO,CAAC,YAAY;CAsBrB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { FieldUIHints, ObjectRegistry } from '@happyvertical/smrt-core';
|
|
2
|
+
import { FieldPolicyDelta, FieldPolicyVisibility } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Field map for one object, keyed by field name (includes inherited fields).
|
|
5
|
+
* Derived structurally from the PUBLIC `ObjectRegistry.getAllFields` return
|
|
6
|
+
* type — core does not export its internal `RegisteredField` name.
|
|
7
|
+
*/
|
|
8
|
+
export type FieldDefinitionMap = Awaited<ReturnType<typeof ObjectRegistry.getAllFields>>;
|
|
9
|
+
/** One field's registered metadata, as returned by `getAllFields`. */
|
|
10
|
+
export type RegisteredFieldInfo = FieldDefinitionMap extends Map<string, infer F> ? F : never;
|
|
11
|
+
/**
|
|
12
|
+
* Resolve `objectRef` (qualified `@package/name:ClassName`) against the live
|
|
13
|
+
* registry, throwing a descriptive error when the class is unknown.
|
|
14
|
+
*/
|
|
15
|
+
export declare function requireRegisteredObject(objectRef: string): void;
|
|
16
|
+
/** Load the full (inherited) field map for a registered objectRef. */
|
|
17
|
+
export declare function getObjectFieldMap(objectRef: string): Promise<FieldDefinitionMap>;
|
|
18
|
+
/**
|
|
19
|
+
* Narrow a manifest `_meta.ui` bag to the known {@link FieldUIHints} keys with
|
|
20
|
+
* their expected primitive types, dropping junk (mirrors the sanitization the
|
|
21
|
+
* web emission applies in core's `web-collections.ts`).
|
|
22
|
+
*/
|
|
23
|
+
export declare function sanitizeFieldUIHints(value: unknown): FieldUIHints | undefined;
|
|
24
|
+
/** Security rail: `sensitive` may live top-level or under `_meta` (STI merges). */
|
|
25
|
+
export declare function isSensitiveField(field: RegisteredFieldInfo): boolean;
|
|
26
|
+
/** Security rail: `readPermission` may live top-level or under `_meta`. */
|
|
27
|
+
export declare function getFieldReadPermission(field: RegisteredFieldInfo): string | undefined;
|
|
28
|
+
export declare function isTransientField(field: RegisteredFieldInfo): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* True when a registered field can receive a policy row. Keep this shared by
|
|
31
|
+
* the resolver and the catalog audit: otherwise a row that never resolves can
|
|
32
|
+
* accidentally be presented as an editable setting.
|
|
33
|
+
*/
|
|
34
|
+
export declare function isPolicyAddressableField(field: RegisteredFieldInfo): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* A field is required when flagged required and not explicitly nullable.
|
|
37
|
+
*
|
|
38
|
+
* `nullable` is read from BOTH the top level and `_meta` for the same reason
|
|
39
|
+
* `sensitive`/`readPermission`/`transient` are: registrations reach the
|
|
40
|
+
* registry through several paths (decorator, manifest, STI merge) and land the
|
|
41
|
+
* flag in either place. Checking only one side made the pair asymmetric —
|
|
42
|
+
* `required` was read from both while `nullable` was read from one.
|
|
43
|
+
*/
|
|
44
|
+
export declare function isRequiredField(field: RegisteredFieldInfo): boolean;
|
|
45
|
+
/** The manifest/code default for a field, boxed; `undefined` when none. */
|
|
46
|
+
export declare function getCodeDefault(field: RegisteredFieldInfo): {
|
|
47
|
+
value: unknown;
|
|
48
|
+
} | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* A resolved default satisfies the required-field invariant only when it is a
|
|
51
|
+
* value a form could actually submit: explicit `null` and the empty string do
|
|
52
|
+
* not count (a required text field "defaulting" to `''` is still unfilled).
|
|
53
|
+
*/
|
|
54
|
+
export declare function isUsableRequiredDefault(defaultBox: {
|
|
55
|
+
value: unknown;
|
|
56
|
+
} | undefined): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Compute the code-seed visibility for every field of an object using the
|
|
59
|
+
* cold-start rule (#2046): with no `ui.basic` markers anywhere on the object,
|
|
60
|
+
* every field is `basic`; once any field is marked `basic: true`, unmarked
|
|
61
|
+
* fields default to `advanced` (and an explicit `basic: false` is always
|
|
62
|
+
* `advanced`).
|
|
63
|
+
*/
|
|
64
|
+
export declare function buildCodeSeedVisibility(fields: FieldDefinitionMap): Map<string, FieldPolicyVisibility>;
|
|
65
|
+
/** Code-seed delta for one field (visibility supplied by the cold-start pass). */
|
|
66
|
+
export declare function buildCodeSeedDelta(field: RegisteredFieldInfo, visibility: FieldPolicyVisibility): FieldPolicyDelta;
|
|
67
|
+
/** Code-seed grouping key (`ui.group`) — not overridable by stored rows. */
|
|
68
|
+
export declare function getCodeSeedGroup(field: RegisteredFieldInfo): string | null;
|
|
69
|
+
/**
|
|
70
|
+
* Type-check a parsed default value against the manifest field type.
|
|
71
|
+
*
|
|
72
|
+
* Explicit `null` is allowed only for optional fields (a required field with a
|
|
73
|
+
* null default has no usable default). Unsupported field types reject defaults
|
|
74
|
+
* outright (fail closed).
|
|
75
|
+
*/
|
|
76
|
+
export declare function assertDefaultValueMatchesFieldType(objectRef: string, fieldName: string, field: RegisteredFieldInfo, value: unknown): void;
|
|
77
|
+
//# sourceMappingURL=field-definitions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-definitions.d.ts","sourceRoot":"","sources":["../src/field-definitions.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAE1E;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,CACtC,UAAU,CAAC,OAAO,cAAc,CAAC,YAAY,CAAC,CAC/C,CAAC;AAEF,sEAAsE;AACtE,MAAM,MAAM,mBAAmB,GAC7B,kBAAkB,SAAS,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAE9D;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAa/D;AAED,sEAAsE;AACtE,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,kBAAkB,CAAC,CAG7B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,GAAG,SAAS,CAc7E;AAED,mFAAmF;AACnF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAEpE;AAED,2EAA2E;AAC3E,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,mBAAmB,GACzB,MAAM,GAAG,SAAS,CAMpB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAEpE;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAO5E;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAKnE;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAC5B,KAAK,EAAE,mBAAmB,GACzB;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAQhC;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE;IAAE,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,GACzC,OAAO,CAKT;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,kBAAkB,GACzB,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAuBpC;AAED,kFAAkF;AAClF,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,mBAAmB,EAC1B,UAAU,EAAE,qBAAqB,GAChC,gBAAgB,CAiBlB;AAED,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,GAAG,IAAI,CAE1E;AAUD;;;;;;GAMG;AACH,wBAAgB,kCAAkC,CAChD,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,mBAAmB,EAC1B,KAAK,EAAE,OAAO,GACb,IAAI,CAsEN"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { ExplainedObjectFieldPolicy, ResolvedObjectFieldPolicy, ResolveFieldPolicyOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve the merged field policy for `objectRef` in the given
|
|
4
|
+
* `(tenantId, userId)` context: code seed → app rows → tenant rows (hierarchy
|
|
5
|
+
* walk root → leaf) → user rows. Defaults AND visibility both resolve through
|
|
6
|
+
* the user tier.
|
|
7
|
+
*
|
|
8
|
+
* Results are cached per `(database, objectRef, tenantId, userId)` with a
|
|
9
|
+
* short TTL; `FieldPolicy.save()`/`.delete()` invalidate the object's entries.
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveFieldPolicy(objectRef: string, options?: ResolveFieldPolicyOptions): Promise<ResolvedObjectFieldPolicy>;
|
|
12
|
+
/**
|
|
13
|
+
* The tenant ids whose rows participate in precedence for a tenant, root to
|
|
14
|
+
* leaf. Catalog code uses this instead of reimplementing inheritance-break
|
|
15
|
+
* handling when it decides whether an inherited override is customized.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveSurvivingTenantChainIds(tenantId: string, options?: ResolveFieldPolicyOptions): Promise<string[]>;
|
|
18
|
+
/**
|
|
19
|
+
* Explain variant: the merged result plus ordered per-layer contributions for
|
|
20
|
+
* each field, so the gear UI (#2049, "shows inherited base") and the control
|
|
21
|
+
* panel (#2050, effective-value-per-layer) never re-derive precedence.
|
|
22
|
+
*
|
|
23
|
+
* A user-layer row suppressed by an effective org lock is omitted from the
|
|
24
|
+
* layer list too — the listed layers always reproduce the merged result.
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveFieldPolicyExplained(objectRef: string, options?: ResolveFieldPolicyOptions): Promise<ExplainedObjectFieldPolicy>;
|
|
27
|
+
/**
|
|
28
|
+
* Whether an import failure means `@happyvertical/smrt-users` is simply not
|
|
29
|
+
* installed (→ flat-tenant fallback) rather than installed-but-broken
|
|
30
|
+
* (→ rethrow, surfacing the problem instead of silently losing ancestor
|
|
31
|
+
* locks/defaults).
|
|
32
|
+
*
|
|
33
|
+
* The decision is made on the missing-module TARGET parsed from Node's
|
|
34
|
+
* `Cannot find package/module '<specifier>'` message (walking the full
|
|
35
|
+
* `cause` chain): only a target that IS smrt-users (or one of its subpaths)
|
|
36
|
+
* counts. A transitive failure INSIDE an installed smrt-users names the
|
|
37
|
+
* other package as the target — with the users path merely appearing as the
|
|
38
|
+
* importer — and therefore rethrows. `importWorkspaceModule`'s own
|
|
39
|
+
* source-fallback wrapper ("Failed to load @happyvertical/smrt-users for
|
|
40
|
+
* ...") is also accepted: it is thrown only when the users package itself
|
|
41
|
+
* cannot be located.
|
|
42
|
+
*
|
|
43
|
+
* Exported for direct testing; not re-exported from the package index.
|
|
44
|
+
*/
|
|
45
|
+
export declare function isMissingUsersDependency(error: unknown): boolean;
|
|
46
|
+
//# sourceMappingURL=field-policy-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-policy-resolver.d.ts","sourceRoot":"","sources":["../src/field-policy-resolver.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,0BAA0B,EAQ1B,yBAAyB,EACzB,yBAAyB,EAE1B,MAAM,YAAY,CAAC;AAYpB;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,yBAAyB,CAAC,CAGpC;AAED;;;;GAIG;AACH,wBAAsB,8BAA8B,CAClD,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,MAAM,EAAE,CAAC,CAInB;AAED;;;;;;;GAOG;AACH,wBAAsB,2BAA2B,CAC/C,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,0BAA0B,CAAC,CA0JrC;AA0MD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAsBhE"}
|