@object-ui/data-objectstack 13.1.0 → 13.2.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # @object-ui/data-objectstack
2
2
 
3
+ ## 13.2.0
4
+
5
+ ### Patch Changes
6
+
7
+ - e492b9d: Permission sets — pure separation of **design** (Studio) and **assignment**
8
+ (Setup), per ADR-0056 / epic #2398. A `sys_permission_set` used to render its six
9
+ authorization facets in Setup as raw `[Object]` / JSON textareas, and only
10
+ objects+fields were editable in Studio; this reworks both surfaces.
11
+
12
+ **Setup (assign + read-only):**
13
+ - The six facets (`object_permissions`, `field_permissions`, `system_permissions`,
14
+ `row_level_security`, `tab_permissions`, `admin_scope`) now render read-only on
15
+ the `sys_permission_set` record page as a compact summary (counts, or capability
16
+ chips) plus a **“Design in Studio →”** deep-link into the structured editor
17
+ (`/apps/:appName/metadata/permission/:setName`, env scope). No `[Object]`, no
18
+ JSON — in the record view, inline edit, and the create/edit form. Implemented as
19
+ a `permission-facet-link` field widget stamped onto the six fields via the single
20
+ `ObjectStackAdapter.getObjectSchema` choke point and honored by DetailSection +
21
+ the record form.
22
+ - User assignment (add/remove via `sys_user_permission_set`) is surfaced directly
23
+ on the Setup record page.
24
+
25
+ **Studio (design every facet):** the permission matrix editor gains structured
26
+ editors for the facets that were JSON-only —
27
+ - **System Capabilities**: a multi-select over the live `sys_capability` registry
28
+ (scope-grouped, labelled chips).
29
+ - **Row-Level Security**: per-policy rows (object · operation · enabled) with CEL
30
+ USING/CHECK.
31
+ - **Tab Visibility**: per-tab `visible | hidden | default_on | default_off`.
32
+ - **Delegated Admin Scope**: business-unit + subtree, manage-assignments /
33
+ -bindings / author-env-sets toggles, and an assignable-permission-sets allowlist.
34
+ Assignment was moved out of the editor (it is now a Setup act) — the editor is
35
+ purely a design surface.
36
+
37
+ Storage/types are unchanged; editors read/write the draft’s existing parsed
38
+ fields and tolerate legacy JSON strings on load. Note: env-scope metadata saves of
39
+ these facets do not yet project onto the queryable `sys_permission_set` data
40
+ record the Setup summary reads, so a fresh Studio edit isn’t reflected in Setup’s
41
+ read-only view until the projection refreshes — tracked as a framework follow-up
42
+ (enforcement reads the authoritative metadata).
43
+ - @object-ui/types@13.2.0
44
+ - @object-ui/core@13.2.0
45
+
3
46
  ## 13.1.0
4
47
 
5
48
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -2432,6 +2432,7 @@ var ObjectStackAdapter = class {
2432
2432
  objectName,
2433
2433
  () => this.fetchObjectSchemaFresh(objectName)
2434
2434
  );
2435
+ this.applyFieldWidgetOverrides(objectName, schema);
2435
2436
  return schema;
2436
2437
  } catch (error) {
2437
2438
  const errorObj = error;
@@ -2444,6 +2445,44 @@ var ObjectStackAdapter = class {
2444
2445
  throw createErrorFromResponse(errorObj, `getObjectSchema(${objectName})`);
2445
2446
  }
2446
2447
  }
2448
+ /**
2449
+ * ADR-0056 P2 (epic #2398) — stamp structured-widget hints onto platform
2450
+ * fields whose framework type is a storage primitive (e.g. `textarea`) but
2451
+ * whose authoring UX should be a structured editor. Only the render `widget`
2452
+ * is added; the field's `type` (the storage contract) is untouched. Applied
2453
+ * idempotently to the cached schema so form + detail both honor it. Widget
2454
+ * components are registered as `field:<widget>` in `@object-ui/fields`.
2455
+ */
2456
+ applyFieldWidgetOverrides(objectName, schema) {
2457
+ const OVERRIDES = {
2458
+ // ADR-0056 pure model — a permission set's six authorization facets are
2459
+ // *designed* in Studio's structured editors and only *assigned* (to
2460
+ // users) in Setup. In Setup they render read-only as a summary + a
2461
+ // "Design in Studio →" deep-link (the `permission-facet-link` widget),
2462
+ // never as raw [Object]/JSON. The capability *editor* itself lives in
2463
+ // Studio (epic #2398 P2).
2464
+ sys_permission_set: {
2465
+ object_permissions: "permission-facet-link",
2466
+ field_permissions: "permission-facet-link",
2467
+ system_permissions: "permission-facet-link",
2468
+ row_level_security: "permission-facet-link",
2469
+ tab_permissions: "permission-facet-link",
2470
+ admin_scope: "permission-facet-link"
2471
+ }
2472
+ };
2473
+ const overrides = OVERRIDES[objectName];
2474
+ const fields = schema && typeof schema === "object" ? schema.fields : null;
2475
+ if (!overrides || !fields) return;
2476
+ for (const [fname, widget] of Object.entries(overrides)) {
2477
+ if (Array.isArray(fields)) {
2478
+ const f = fields.find((x) => x?.name === fname);
2479
+ if (f && !f.widget) f.widget = widget;
2480
+ } else {
2481
+ const f = fields[fname];
2482
+ if (f && !f.widget) f.widget = widget;
2483
+ }
2484
+ }
2485
+ }
2447
2486
  /**
2448
2487
  * Fetch a single object's schema while always revalidating the browser cache.
2449
2488
  *
package/dist/index.d.cts CHANGED
@@ -1530,6 +1530,15 @@ declare class ObjectStackAdapter<T = unknown> implements DataSource<T> {
1530
1530
  * @returns Promise resolving to the object schema
1531
1531
  */
1532
1532
  getObjectSchema(objectName: string): Promise<unknown>;
1533
+ /**
1534
+ * ADR-0056 P2 (epic #2398) — stamp structured-widget hints onto platform
1535
+ * fields whose framework type is a storage primitive (e.g. `textarea`) but
1536
+ * whose authoring UX should be a structured editor. Only the render `widget`
1537
+ * is added; the field's `type` (the storage contract) is untouched. Applied
1538
+ * idempotently to the cached schema so form + detail both honor it. Widget
1539
+ * components are registered as `field:<widget>` in `@object-ui/fields`.
1540
+ */
1541
+ private applyFieldWidgetOverrides;
1533
1542
  /**
1534
1543
  * Fetch a single object's schema while always revalidating the browser cache.
1535
1544
  *
package/dist/index.d.ts CHANGED
@@ -1530,6 +1530,15 @@ declare class ObjectStackAdapter<T = unknown> implements DataSource<T> {
1530
1530
  * @returns Promise resolving to the object schema
1531
1531
  */
1532
1532
  getObjectSchema(objectName: string): Promise<unknown>;
1533
+ /**
1534
+ * ADR-0056 P2 (epic #2398) — stamp structured-widget hints onto platform
1535
+ * fields whose framework type is a storage primitive (e.g. `textarea`) but
1536
+ * whose authoring UX should be a structured editor. Only the render `widget`
1537
+ * is added; the field's `type` (the storage contract) is untouched. Applied
1538
+ * idempotently to the cached schema so form + detail both honor it. Widget
1539
+ * components are registered as `field:<widget>` in `@object-ui/fields`.
1540
+ */
1541
+ private applyFieldWidgetOverrides;
1533
1542
  /**
1534
1543
  * Fetch a single object's schema while always revalidating the browser cache.
1535
1544
  *
package/dist/index.js CHANGED
@@ -2384,6 +2384,7 @@ var ObjectStackAdapter = class {
2384
2384
  objectName,
2385
2385
  () => this.fetchObjectSchemaFresh(objectName)
2386
2386
  );
2387
+ this.applyFieldWidgetOverrides(objectName, schema);
2387
2388
  return schema;
2388
2389
  } catch (error) {
2389
2390
  const errorObj = error;
@@ -2396,6 +2397,44 @@ var ObjectStackAdapter = class {
2396
2397
  throw createErrorFromResponse(errorObj, `getObjectSchema(${objectName})`);
2397
2398
  }
2398
2399
  }
2400
+ /**
2401
+ * ADR-0056 P2 (epic #2398) — stamp structured-widget hints onto platform
2402
+ * fields whose framework type is a storage primitive (e.g. `textarea`) but
2403
+ * whose authoring UX should be a structured editor. Only the render `widget`
2404
+ * is added; the field's `type` (the storage contract) is untouched. Applied
2405
+ * idempotently to the cached schema so form + detail both honor it. Widget
2406
+ * components are registered as `field:<widget>` in `@object-ui/fields`.
2407
+ */
2408
+ applyFieldWidgetOverrides(objectName, schema) {
2409
+ const OVERRIDES = {
2410
+ // ADR-0056 pure model — a permission set's six authorization facets are
2411
+ // *designed* in Studio's structured editors and only *assigned* (to
2412
+ // users) in Setup. In Setup they render read-only as a summary + a
2413
+ // "Design in Studio →" deep-link (the `permission-facet-link` widget),
2414
+ // never as raw [Object]/JSON. The capability *editor* itself lives in
2415
+ // Studio (epic #2398 P2).
2416
+ sys_permission_set: {
2417
+ object_permissions: "permission-facet-link",
2418
+ field_permissions: "permission-facet-link",
2419
+ system_permissions: "permission-facet-link",
2420
+ row_level_security: "permission-facet-link",
2421
+ tab_permissions: "permission-facet-link",
2422
+ admin_scope: "permission-facet-link"
2423
+ }
2424
+ };
2425
+ const overrides = OVERRIDES[objectName];
2426
+ const fields = schema && typeof schema === "object" ? schema.fields : null;
2427
+ if (!overrides || !fields) return;
2428
+ for (const [fname, widget] of Object.entries(overrides)) {
2429
+ if (Array.isArray(fields)) {
2430
+ const f = fields.find((x) => x?.name === fname);
2431
+ if (f && !f.widget) f.widget = widget;
2432
+ } else {
2433
+ const f = fields[fname];
2434
+ if (f && !f.widget) f.widget = widget;
2435
+ }
2436
+ }
2437
+ }
2399
2438
  /**
2400
2439
  * Fetch a single object's schema while always revalidating the browser cache.
2401
2440
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@object-ui/data-objectstack",
3
- "version": "13.1.0",
3
+ "version": "13.2.0",
4
4
  "description": "ObjectStack Data Adapter for Object UI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -22,9 +22,9 @@
22
22
  "LICENSE"
23
23
  ],
24
24
  "dependencies": {
25
- "@objectstack/client": "^12.3.0",
26
- "@object-ui/core": "13.1.0",
27
- "@object-ui/types": "13.1.0"
25
+ "@objectstack/client": "^14.3.0",
26
+ "@object-ui/core": "13.2.0",
27
+ "@object-ui/types": "13.2.0"
28
28
  },
29
29
  "devDependencies": {
30
30
  "tsup": "^8.5.1",
package/src/index.ts CHANGED
@@ -1608,7 +1608,13 @@ export class ObjectStackAdapter<T = unknown> implements DataSource<T> {
1608
1608
  const schema = await this.metadataCache.get(objectName, () =>
1609
1609
  this.fetchObjectSchemaFresh(objectName),
1610
1610
  );
1611
-
1611
+
1612
+ // ADR-0056 P2 (epic #2398): stamp structured-widget hints onto specific
1613
+ // platform fields. This is the single choke point both the record form
1614
+ // (ObjectForm) and the detail view (DetailView/DetailSection) read the
1615
+ // schema through, so one pass here reaches every edit surface.
1616
+ this.applyFieldWidgetOverrides(objectName, schema);
1617
+
1612
1618
  return schema;
1613
1619
  } catch (error: unknown) {
1614
1620
  // Check if it's a 404 error
@@ -1626,6 +1632,46 @@ export class ObjectStackAdapter<T = unknown> implements DataSource<T> {
1626
1632
  }
1627
1633
  }
1628
1634
 
1635
+ /**
1636
+ * ADR-0056 P2 (epic #2398) — stamp structured-widget hints onto platform
1637
+ * fields whose framework type is a storage primitive (e.g. `textarea`) but
1638
+ * whose authoring UX should be a structured editor. Only the render `widget`
1639
+ * is added; the field's `type` (the storage contract) is untouched. Applied
1640
+ * idempotently to the cached schema so form + detail both honor it. Widget
1641
+ * components are registered as `field:<widget>` in `@object-ui/fields`.
1642
+ */
1643
+ private applyFieldWidgetOverrides(objectName: string, schema: unknown): void {
1644
+ const OVERRIDES: Record<string, Record<string, string>> = {
1645
+ // ADR-0056 pure model — a permission set's six authorization facets are
1646
+ // *designed* in Studio's structured editors and only *assigned* (to
1647
+ // users) in Setup. In Setup they render read-only as a summary + a
1648
+ // "Design in Studio →" deep-link (the `permission-facet-link` widget),
1649
+ // never as raw [Object]/JSON. The capability *editor* itself lives in
1650
+ // Studio (epic #2398 P2).
1651
+ sys_permission_set: {
1652
+ object_permissions: 'permission-facet-link',
1653
+ field_permissions: 'permission-facet-link',
1654
+ system_permissions: 'permission-facet-link',
1655
+ row_level_security: 'permission-facet-link',
1656
+ tab_permissions: 'permission-facet-link',
1657
+ admin_scope: 'permission-facet-link',
1658
+ },
1659
+ };
1660
+ const overrides = OVERRIDES[objectName];
1661
+ const fields =
1662
+ schema && typeof schema === 'object' ? (schema as { fields?: unknown }).fields : null;
1663
+ if (!overrides || !fields) return;
1664
+ for (const [fname, widget] of Object.entries(overrides)) {
1665
+ if (Array.isArray(fields)) {
1666
+ const f = fields.find((x: any) => x?.name === fname);
1667
+ if (f && !f.widget) f.widget = widget;
1668
+ } else {
1669
+ const f = (fields as Record<string, any>)[fname];
1670
+ if (f && !f.widget) f.widget = widget;
1671
+ }
1672
+ }
1673
+ }
1674
+
1629
1675
  /**
1630
1676
  * Fetch a single object's schema while always revalidating the browser cache.
1631
1677
  *