@jini-ai/admin 0.3.7 → 0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/index.d.ts +0 -3
- package/dist/core/index.js +0 -1
- package/dist/core/ports/index.d.ts +0 -1
- package/dist/core/ports/menus.d.ts +0 -43
- package/dist/core/ports/menus.js +0 -43
- package/dist/react/components/ConfirmDialog/ConfirmDialog.d.ts +2 -1
- package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.d.ts +37 -1
- package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.js +42 -1
- package/dist/react/components/ConfirmDialog/ConfirmDialog.js +2 -3
- package/dist/react/components/Sidebar.js +2 -90
- package/dist/react/index.d.ts +3 -1
- package/dist/react/index.js +5 -3
- package/package.json +5 -4
- package/dist/browser/index.d.ts.map +0 -1
- package/dist/browser/index.js.map +0 -1
- package/dist/browser/navigation.d.ts.map +0 -1
- package/dist/browser/navigation.js.map +0 -1
- package/dist/core/data-table/types.d.ts.map +0 -1
- package/dist/core/data-table/types.js.map +0 -1
- package/dist/core/entities/rules.d.ts +0 -138
- package/dist/core/entities/rules.d.ts.map +0 -1
- package/dist/core/entities/rules.js +0 -344
- package/dist/core/entities/rules.js.map +0 -1
- package/dist/core/gated/types.d.ts.map +0 -1
- package/dist/core/gated/types.js.map +0 -1
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js.map +0 -1
- package/dist/core/manifest/rules.d.ts.map +0 -1
- package/dist/core/manifest/rules.js.map +0 -1
- package/dist/core/manifest/types.d.ts.map +0 -1
- package/dist/core/manifest/types.js.map +0 -1
- package/dist/core/permissions/rules.d.ts.map +0 -1
- package/dist/core/permissions/rules.js.map +0 -1
- package/dist/core/ports/analytics.d.ts.map +0 -1
- package/dist/core/ports/analytics.js.map +0 -1
- package/dist/core/ports/auth.d.ts.map +0 -1
- package/dist/core/ports/auth.js.map +0 -1
- package/dist/core/ports/comments.d.ts.map +0 -1
- package/dist/core/ports/comments.js.map +0 -1
- package/dist/core/ports/database.d.ts.map +0 -1
- package/dist/core/ports/database.js.map +0 -1
- package/dist/core/ports/entities.d.ts +0 -302
- package/dist/core/ports/entities.d.ts.map +0 -1
- package/dist/core/ports/entities.js +0 -47
- package/dist/core/ports/entities.js.map +0 -1
- package/dist/core/ports/forms.d.ts.map +0 -1
- package/dist/core/ports/forms.js.map +0 -1
- package/dist/core/ports/identity.d.ts.map +0 -1
- package/dist/core/ports/identity.js.map +0 -1
- package/dist/core/ports/index.d.ts.map +0 -1
- package/dist/core/ports/index.js.map +0 -1
- package/dist/core/ports/integrations.d.ts.map +0 -1
- package/dist/core/ports/integrations.js.map +0 -1
- package/dist/core/ports/media.d.ts.map +0 -1
- package/dist/core/ports/media.js.map +0 -1
- package/dist/core/ports/members.d.ts.map +0 -1
- package/dist/core/ports/members.js.map +0 -1
- package/dist/core/ports/menus.d.ts.map +0 -1
- package/dist/core/ports/menus.js.map +0 -1
- package/dist/core/ports/plugins.d.ts.map +0 -1
- package/dist/core/ports/plugins.js.map +0 -1
- package/dist/core/ports/recovery.d.ts.map +0 -1
- package/dist/core/ports/recovery.js.map +0 -1
- package/dist/core/ports/redirects.d.ts.map +0 -1
- package/dist/core/ports/redirects.js.map +0 -1
- package/dist/core/ports/seo.d.ts.map +0 -1
- package/dist/core/ports/seo.js.map +0 -1
- package/dist/core/ports/settings.d.ts.map +0 -1
- package/dist/core/ports/settings.js.map +0 -1
- package/dist/core/ports/workspace.d.ts.map +0 -1
- package/dist/core/ports/workspace.js.map +0 -1
- package/dist/core/routing/rules.d.ts.map +0 -1
- package/dist/core/routing/rules.js.map +0 -1
- package/dist/core/routing/types.d.ts.map +0 -1
- package/dist/core/routing/types.js.map +0 -1
- package/dist/core/transport/errors.d.ts.map +0 -1
- package/dist/core/transport/errors.js.map +0 -1
- package/dist/core/transport/http.d.ts.map +0 -1
- package/dist/core/transport/http.js.map +0 -1
- package/dist/core/transport/index.d.ts.map +0 -1
- package/dist/core/transport/index.js.map +0 -1
- package/dist/core/transport/types.d.ts.map +0 -1
- package/dist/core/transport/types.js.map +0 -1
- package/dist/react/components/ConfirmButton/ConfirmButton.d.ts.map +0 -1
- package/dist/react/components/ConfirmButton/ConfirmButton.hooks.d.ts.map +0 -1
- package/dist/react/components/ConfirmButton/ConfirmButton.hooks.js.map +0 -1
- package/dist/react/components/ConfirmButton/ConfirmButton.js.map +0 -1
- package/dist/react/components/ConfirmButton.d.ts +0 -39
- package/dist/react/components/ConfirmButton.d.ts.map +0 -1
- package/dist/react/components/ConfirmButton.js +0 -79
- package/dist/react/components/ConfirmButton.js.map +0 -1
- package/dist/react/components/ConfirmDialog/ConfirmDialog.d.ts.map +0 -1
- package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.d.ts.map +0 -1
- package/dist/react/components/ConfirmDialog/ConfirmDialog.hooks.js.map +0 -1
- package/dist/react/components/ConfirmDialog/ConfirmDialog.js.map +0 -1
- package/dist/react/components/ConfirmDialog.d.ts +0 -57
- package/dist/react/components/ConfirmDialog.d.ts.map +0 -1
- package/dist/react/components/ConfirmDialog.js +0 -85
- package/dist/react/components/ConfirmDialog.js.map +0 -1
- package/dist/react/components/DataTable.d.ts.map +0 -1
- package/dist/react/components/DataTable.js.map +0 -1
- package/dist/react/components/InteractiveHtmlEditor/InteractiveHtmlEditor.d.ts.map +0 -1
- package/dist/react/components/InteractiveHtmlEditor/InteractiveHtmlEditor.js.map +0 -1
- package/dist/react/components/RowMenu/RowMenu.d.ts.map +0 -1
- package/dist/react/components/RowMenu/RowMenu.hooks.d.ts.map +0 -1
- package/dist/react/components/RowMenu/RowMenu.hooks.js.map +0 -1
- package/dist/react/components/RowMenu/RowMenu.js.map +0 -1
- package/dist/react/components/RowMenu.d.ts +0 -44
- package/dist/react/components/RowMenu.d.ts.map +0 -1
- package/dist/react/components/RowMenu.js +0 -149
- package/dist/react/components/RowMenu.js.map +0 -1
- package/dist/react/components/Sidebar.d.ts.map +0 -1
- package/dist/react/components/Sidebar.js.map +0 -1
- package/dist/react/hooks/use-nav-sections.d.ts.map +0 -1
- package/dist/react/hooks/use-nav-sections.js.map +0 -1
- package/dist/react/hooks/use-sidebar-rail.d.ts.map +0 -1
- package/dist/react/hooks/use-sidebar-rail.js.map +0 -1
- package/dist/react/index.d.ts.map +0 -1
- package/dist/react/index.js.map +0 -1
- package/dist/react/types.d.ts.map +0 -1
- package/dist/react/types.js.map +0 -1
- package/dist/server/composio/bounded-data.d.ts +0 -36
- package/dist/server/composio/bounded-data.d.ts.map +0 -1
- package/dist/server/composio/bounded-data.js +0 -181
- package/dist/server/composio/bounded-data.js.map +0 -1
- package/dist/server/composio/catalog.d.ts +0 -147
- package/dist/server/composio/catalog.d.ts.map +0 -1
- package/dist/server/composio/catalog.js +0 -126
- package/dist/server/composio/catalog.js.map +0 -1
- package/dist/server/composio/composio-config.d.ts +0 -42
- package/dist/server/composio/composio-config.d.ts.map +0 -1
- package/dist/server/composio/composio-config.js +0 -145
- package/dist/server/composio/composio-config.js.map +0 -1
- package/dist/server/composio/composio-descriptions.d.ts +0 -16
- package/dist/server/composio/composio-descriptions.d.ts.map +0 -1
- package/dist/server/composio/composio-descriptions.js +0 -766
- package/dist/server/composio/composio-descriptions.js.map +0 -1
- package/dist/server/composio/composio.d.ts +0 -364
- package/dist/server/composio/composio.d.ts.map +0 -1
- package/dist/server/composio/composio.js +0 -1902
- package/dist/server/composio/composio.js.map +0 -1
- package/dist/server/composio/errors.d.ts +0 -15
- package/dist/server/composio/errors.d.ts.map +0 -1
- package/dist/server/composio/errors.js +0 -16
- package/dist/server/composio/errors.js.map +0 -1
- package/dist/server/composio/file-lock.d.ts +0 -13
- package/dist/server/composio/file-lock.d.ts.map +0 -1
- package/dist/server/composio/file-lock.js +0 -92
- package/dist/server/composio/file-lock.js.map +0 -1
- package/dist/server/composio/index.d.ts +0 -18
- package/dist/server/composio/index.d.ts.map +0 -1
- package/dist/server/composio/index.js +0 -7
- package/dist/server/composio/index.js.map +0 -1
- package/dist/server/composio/json-schema.d.ts +0 -93
- package/dist/server/composio/json-schema.d.ts.map +0 -1
- package/dist/server/composio/json-schema.js +0 -498
- package/dist/server/composio/json-schema.js.map +0 -1
- package/dist/server/composio/output-protection.d.ts +0 -32
- package/dist/server/composio/output-protection.d.ts.map +0 -1
- package/dist/server/composio/output-protection.js +0 -105
- package/dist/server/composio/output-protection.js.map +0 -1
- package/dist/server/composio/service.d.ts +0 -181
- package/dist/server/composio/service.d.ts.map +0 -1
- package/dist/server/composio/service.js +0 -758
- package/dist/server/composio/service.js.map +0 -1
- package/dist/server/index.d.ts +0 -15
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/index.js +0 -15
- package/dist/server/index.js.map +0 -1
package/dist/core/index.d.ts
CHANGED
|
@@ -18,7 +18,4 @@ export type { GatedConfirmResult, GatedOperation, GatedPlanResult } from './gate
|
|
|
18
18
|
export type { DataTableSortDirection, DataTableSortState } from './data-table/types.js';
|
|
19
19
|
export type { AdminAnalyticsHit, AdminAnalyticsPort, AdminAuthPort, AdminAuthUser, AdminComment, AdminCommentsPort, AdminCommentsQueuePage, AdminDatabasePort, AdminDegradedBanner, AdminDisclosureResult, AdminExtensionEnabledResult, AdminExtensionsPort, AdminIdentityPort, AdminIdentityUser, AdminIntegrationDelivery, AdminIntegrationDeliverySummary, AdminIntegrationSubscription, AdminIntegrationsPort, AdminLedgerRow, AdminMedia, AdminMediaPort, AdminMember, AdminMembersPort, AdminPlugin, AdminPolicy, AdminRecoveryDeepLinkResult, AdminRecoveryPort, AdminRecoveryStatus, AdminRestorePoint, AdminRestorePointSummary, AdminRole, AdminSettingsPort, AdminWorkspace, AdminWorkspacePort, CategoryCount, CommentModerationAction, CommentsSettings, CommentStatus, DatabaseContextEnvelope, DegradedBannerActionKind, DegradedBannerKind, MigrateForwardResult, RestoreConfirmInput, RestoreExecuteInput, RestoreExecuteResult, RestorePointCostClass, SettingResolvedValue, SettingResetResponse, SettingScope, SettingValueResponse, } from './ports/index.js';
|
|
20
20
|
export type { AdminAssignMenuLocationResult, AdminDeleteMenuResult, AdminFormCreateInput, AdminFormDefinition, AdminFormField, AdminFormNotifyConfig, AdminFormsPort, AdminFormSubmission, AdminFormSubmissionPage, AdminFormUpdatePatch, AdminMenu, AdminMenuBinding, AdminMenuCreateInput, AdminMenuCustomTarget, AdminMenuEntryTarget, AdminMenuItem, AdminMenuItemAttrs, AdminMenuRouteTarget, AdminMenusPort, AdminMenuTarget, AdminMenuTermTarget, AdminMenuUpdateTreeInput, AdminMenuUrlTarget, AdminRedirect, AdminRedirectCreateInput, AdminRedirectHitStats, AdminRedirectImportFailure, AdminRedirectImportResult, AdminRedirectListFilter, AdminRedirectsPort, AdminRedirectUpdatePatch, AdminSeoAnalysis, AdminSeoIssue, AdminSeoMeta, AdminSeoOpenGraph, AdminSeoOverrides, AdminSeoPort, AdminSeoRobotsDirective, AdminSeoRobotsRule, AdminSeoSettings, AdminSeoTwitterCard, FormDefinitionStatus, FormFieldType, MenuStatus, NavTargetKind, RedirectMatchType, RedirectSource, RedirectStatus, RedirectStatusCode, SeoIssueSeverity, SeoOpenGraphType, SeoTwitterCardKind, } from './ports/index.js';
|
|
21
|
-
export type { AdminEntityDescriptor, AdminEntityField, AdminEntityFieldKind, AdminEntityFilter, AdminEntityJsonField, AdminEntityListQuery, AdminEntityPage, AdminEntityPort, AdminEntityRegistry, AdminEntityRelationField, AdminEntityRow, AdminEntityRowData, AdminEntityScalarField, AdminErasedEntityPort, } from './ports/index.js';
|
|
22
|
-
export { createAdminEntityRegistry, describeAdminEntityFieldMismatch, eraseEntityPort, getErasedEntityPort, listErasedEntityPorts, } from './entities/rules.js';
|
|
23
|
-
export type { AdminEntityErasureOptions, AdminEntityRowViolation } from './entities/rules.js';
|
|
24
21
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/core/index.js
CHANGED
|
@@ -12,5 +12,4 @@ export { DEFAULT_ADMIN_BASE, adminHref, currentRoutePath, matchRoute, stripTrail
|
|
|
12
12
|
export { hasPermission } from './permissions/rules.js';
|
|
13
13
|
// Transport — the seam every route group is built on.
|
|
14
14
|
export { AdminApiError, createAdminClient, createHttpTransport, describeApiError, } from './transport/index.js';
|
|
15
|
-
export { createAdminEntityRegistry, describeAdminEntityFieldMismatch, eraseEntityPort, getErasedEntityPort, listErasedEntityPorts, } from './entities/rules.js';
|
|
16
15
|
//# sourceMappingURL=index.js.map
|
|
@@ -18,5 +18,4 @@ export type { AdminSeoAnalysis, AdminSeoIssue, AdminSeoMeta, AdminSeoOpenGraph,
|
|
|
18
18
|
export type { AdminRedirect, AdminRedirectCreateInput, AdminRedirectHitStats, AdminRedirectImportFailure, AdminRedirectImportResult, AdminRedirectListFilter, AdminRedirectsPort, AdminRedirectUpdatePatch, RedirectMatchType, RedirectSource, RedirectStatus, RedirectStatusCode, } from './redirects.js';
|
|
19
19
|
export type { AdminAssignMenuLocationResult, AdminDeleteMenuResult, AdminMenu, AdminMenuBinding, AdminMenuCreateInput, AdminMenuCustomTarget, AdminMenuEntryTarget, AdminMenuItem, AdminMenuItemAttrs, AdminMenuRouteTarget, AdminMenusPort, AdminMenuTarget, AdminMenuTermTarget, AdminMenuUpdateTreeInput, AdminMenuUrlTarget, MenuStatus, NavTargetKind, } from './menus.js';
|
|
20
20
|
export type { AdminFormCreateInput, AdminFormDefinition, AdminFormField, AdminFormNotifyConfig, AdminFormsPort, AdminFormSubmission, AdminFormSubmissionPage, AdminFormUpdatePatch, FormDefinitionStatus, FormFieldType, } from './forms.js';
|
|
21
|
-
export type { AdminEntityDescriptor, AdminEntityField, AdminEntityFieldKind, AdminEntityFilter, AdminEntityJsonField, AdminEntityListQuery, AdminEntityPage, AdminEntityPort, AdminEntityRegistry, AdminEntityRelationField, AdminEntityRow, AdminEntityRowData, AdminEntityScalarField, AdminErasedEntityPort, } from './entities.js';
|
|
22
21
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -25,20 +25,6 @@
|
|
|
25
25
|
* `kind` values (with `AdminMenuCustomTarget` as the `default` arm) is the straightforward way to
|
|
26
26
|
* stay correct.
|
|
27
27
|
*
|
|
28
|
-
* **Migration hazard, measured 2026-09-05.** This is not merely a style preference — it means an
|
|
29
|
-
* exhaustive `switch` with NO `default` arm cannot compile against `AdminMenuTarget` at all, and
|
|
30
|
-
* that is exactly the shape a host arrives with. Both existing admin apps' `targetForKind`
|
|
31
|
-
* (`apps/admin/src/features/menus/MenuEditor.tsx`) switch over their own local CLOSED four-member
|
|
32
|
-
* union with no `default`, and rely on exhaustiveness for the return type. Compiling that function
|
|
33
|
-
* against this port's union emits `TS2366` (lacks ending return statement) plus a `TS2339` per
|
|
34
|
-
* field access. Confirmed by compiling the real function against this union directly.
|
|
35
|
-
*
|
|
36
|
-
* The hazard is pre-existing and belongs to `AdminMenuCustomTarget`, not to any later change: the
|
|
37
|
-
* identical probe run against the union with and without an extra member emits a character-for-
|
|
38
|
-
* character identical error set. Recorded here because it will surface the first time anyone wires
|
|
39
|
-
* a host onto this port, and the natural instinct will be to blame whatever change is in flight at
|
|
40
|
-
* that moment. The fix is a `default` arm in the host, not a change to this file.
|
|
41
|
-
*
|
|
42
28
|
* **This is a deliberately deferred decision, not a settled one — record it as such.** `entryRef`/
|
|
43
29
|
* `termRef` encode a host content model (an "entry" and a "taxonomy term" are the reference
|
|
44
30
|
* implementation's own vocabulary for its content system, not a vendor-neutral abstraction this
|
|
@@ -53,35 +39,6 @@
|
|
|
53
39
|
* instead of one, and a genuine vendor-neutral reference shape (rather than another bespoke
|
|
54
40
|
* `kind`-per-host member) becomes the right call.
|
|
55
41
|
*
|
|
56
|
-
* ### Status of that trigger, re-checked 2026-09-05 — NOT fired
|
|
57
|
-
*
|
|
58
|
-
* A second host now exists in this workspace, and that is NOT the trigger. The trigger is a second
|
|
59
|
-
* host needing a fifth KIND. Recording the difference here because a promotion was very nearly
|
|
60
|
-
* approved on the weaker reading. Four findings, all verified against source rather than assumed:
|
|
61
|
-
*
|
|
62
|
-
* 1. **Zero importers.** Nothing anywhere imports `AdminMenuTarget`, `NavTargetKind`, or any target
|
|
63
|
-
* variant from this package. In this repo they are re-exported by `core/index.ts` and
|
|
64
|
-
* `core/ports/index.ts` and consumed by nothing.
|
|
65
|
-
* 2. **Both admin apps declare their own.** Each ships a local, *closed*
|
|
66
|
-
* `{ kind: "entryRef" | "termRef" | "url" | "route" }` in its own `src/lib/api.ts` — an HTTP
|
|
67
|
-
* DTO, not this port. The two are byte-identical to each other: the second is a fork of the
|
|
68
|
-
* first, so they are one data point, not two.
|
|
69
|
-
* 3. **The other `NavTargetKind` is a different type.** `@jini-ai/cms/navigation` exports its own
|
|
70
|
-
* `NavTargetKind` (closed, plus a separate `ReservedNavTargetKind`). A host importing that one
|
|
71
|
-
* is not exercising this port.
|
|
72
|
-
* 4. **The union is already open.** `AdminMenuCustomTarget`'s `kind: string & {}` already lets any
|
|
73
|
-
* host express any kind today. Nothing is blocked while the decision stays deferred.
|
|
74
|
-
*
|
|
75
|
-
* So no fifth kind has been needed, and adding a named generic variant now would be designing from
|
|
76
|
-
* zero validating examples — the exact failure the paragraph above exists to prevent. Considered
|
|
77
|
-
* and rejected on 2026-09-05 for that reason. Re-check this section, not the prose above it,
|
|
78
|
-
* before concluding the trigger has fired.
|
|
79
|
-
*
|
|
80
|
-
* Note for whoever revisits: wiring `AdminMenusPort` into a host is the experiment that ANSWERS the
|
|
81
|
-
* type question, and it is not blocked by it. A host that wires the port and finds
|
|
82
|
-
* `entryRef`/`termRef` fit vindicates the deferral; one that needs a product/collection kind fires
|
|
83
|
-
* the trigger with a real second example to design from.
|
|
84
|
-
*
|
|
85
42
|
* ## `deleteMenu` is a two-rung ladder driven by call count, not by `force` alone
|
|
86
43
|
*
|
|
87
44
|
* A single method models a two-step deletion flow: the FIRST call against a non-trashed menu
|
package/dist/core/ports/menus.js
CHANGED
|
@@ -25,20 +25,6 @@
|
|
|
25
25
|
* `kind` values (with `AdminMenuCustomTarget` as the `default` arm) is the straightforward way to
|
|
26
26
|
* stay correct.
|
|
27
27
|
*
|
|
28
|
-
* **Migration hazard, measured 2026-09-05.** This is not merely a style preference — it means an
|
|
29
|
-
* exhaustive `switch` with NO `default` arm cannot compile against `AdminMenuTarget` at all, and
|
|
30
|
-
* that is exactly the shape a host arrives with. Both existing admin apps' `targetForKind`
|
|
31
|
-
* (`apps/admin/src/features/menus/MenuEditor.tsx`) switch over their own local CLOSED four-member
|
|
32
|
-
* union with no `default`, and rely on exhaustiveness for the return type. Compiling that function
|
|
33
|
-
* against this port's union emits `TS2366` (lacks ending return statement) plus a `TS2339` per
|
|
34
|
-
* field access. Confirmed by compiling the real function against this union directly.
|
|
35
|
-
*
|
|
36
|
-
* The hazard is pre-existing and belongs to `AdminMenuCustomTarget`, not to any later change: the
|
|
37
|
-
* identical probe run against the union with and without an extra member emits a character-for-
|
|
38
|
-
* character identical error set. Recorded here because it will surface the first time anyone wires
|
|
39
|
-
* a host onto this port, and the natural instinct will be to blame whatever change is in flight at
|
|
40
|
-
* that moment. The fix is a `default` arm in the host, not a change to this file.
|
|
41
|
-
*
|
|
42
28
|
* **This is a deliberately deferred decision, not a settled one — record it as such.** `entryRef`/
|
|
43
29
|
* `termRef` encode a host content model (an "entry" and a "taxonomy term" are the reference
|
|
44
30
|
* implementation's own vocabulary for its content system, not a vendor-neutral abstraction this
|
|
@@ -53,35 +39,6 @@
|
|
|
53
39
|
* instead of one, and a genuine vendor-neutral reference shape (rather than another bespoke
|
|
54
40
|
* `kind`-per-host member) becomes the right call.
|
|
55
41
|
*
|
|
56
|
-
* ### Status of that trigger, re-checked 2026-09-05 — NOT fired
|
|
57
|
-
*
|
|
58
|
-
* A second host now exists in this workspace, and that is NOT the trigger. The trigger is a second
|
|
59
|
-
* host needing a fifth KIND. Recording the difference here because a promotion was very nearly
|
|
60
|
-
* approved on the weaker reading. Four findings, all verified against source rather than assumed:
|
|
61
|
-
*
|
|
62
|
-
* 1. **Zero importers.** Nothing anywhere imports `AdminMenuTarget`, `NavTargetKind`, or any target
|
|
63
|
-
* variant from this package. In this repo they are re-exported by `core/index.ts` and
|
|
64
|
-
* `core/ports/index.ts` and consumed by nothing.
|
|
65
|
-
* 2. **Both admin apps declare their own.** Each ships a local, *closed*
|
|
66
|
-
* `{ kind: "entryRef" | "termRef" | "url" | "route" }` in its own `src/lib/api.ts` — an HTTP
|
|
67
|
-
* DTO, not this port. The two are byte-identical to each other: the second is a fork of the
|
|
68
|
-
* first, so they are one data point, not two.
|
|
69
|
-
* 3. **The other `NavTargetKind` is a different type.** `@jini-ai/cms/navigation` exports its own
|
|
70
|
-
* `NavTargetKind` (closed, plus a separate `ReservedNavTargetKind`). A host importing that one
|
|
71
|
-
* is not exercising this port.
|
|
72
|
-
* 4. **The union is already open.** `AdminMenuCustomTarget`'s `kind: string & {}` already lets any
|
|
73
|
-
* host express any kind today. Nothing is blocked while the decision stays deferred.
|
|
74
|
-
*
|
|
75
|
-
* So no fifth kind has been needed, and adding a named generic variant now would be designing from
|
|
76
|
-
* zero validating examples — the exact failure the paragraph above exists to prevent. Considered
|
|
77
|
-
* and rejected on 2026-09-05 for that reason. Re-check this section, not the prose above it,
|
|
78
|
-
* before concluding the trigger has fired.
|
|
79
|
-
*
|
|
80
|
-
* Note for whoever revisits: wiring `AdminMenusPort` into a host is the experiment that ANSWERS the
|
|
81
|
-
* type question, and it is not blocked by it. A host that wires the port and finds
|
|
82
|
-
* `entryRef`/`termRef` fit vindicates the deferral; one that needs a product/collection kind fires
|
|
83
|
-
* the trigger with a real second example to design from.
|
|
84
|
-
*
|
|
85
42
|
* ## `deleteMenu` is a two-rung ladder driven by call count, not by `force` alone
|
|
86
43
|
*
|
|
87
44
|
* A single method models a two-step deletion flow: the FIRST call against a non-trashed menu
|
|
@@ -51,7 +51,8 @@ export interface ConfirmDialogProps {
|
|
|
51
51
|
title: string;
|
|
52
52
|
body: ReactNode;
|
|
53
53
|
confirmLabel: string;
|
|
54
|
-
/** @default "Cancel"
|
|
54
|
+
/** @default the enclosing `ConfirmDialogDefaultsProvider`'s `cancelLabel`, or "Cancel" with
|
|
55
|
+
* none mounted. */
|
|
55
56
|
cancelLabel?: string;
|
|
56
57
|
/** Applies `.btn-warning`/`.btn-danger` to the confirm action. Defaults to `"default"` (no class,
|
|
57
58
|
* the plain primary button). Wins over `destructive` below when both are passed. */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type MouseEvent, type RefObject, type SyntheticEvent } from 'react';
|
|
1
|
+
import { type MouseEvent, type ReactNode, type RefObject, type SyntheticEvent } from 'react';
|
|
2
2
|
/**
|
|
3
3
|
* @file `ConfirmDialog`'s open/close and focus-management state, split out of the component so it
|
|
4
4
|
* can be swapped for a fake via the `useDialog` prop on `ConfirmDialogProps` — see that prop's doc
|
|
@@ -33,6 +33,42 @@ export interface ConfirmDialogController {
|
|
|
33
33
|
/** The signature `ConfirmDialogProps.useDialog` accepts. Any hook matching this can drive the
|
|
34
34
|
* component; it does not have to be {@link useConfirmDialog}, or even use React state at all. */
|
|
35
35
|
export type UseConfirmDialog = (open: boolean, pending: boolean | undefined, onCancel: () => void) => ConfirmDialogController;
|
|
36
|
+
/**
|
|
37
|
+
* Host-wide defaults every `ConfirmDialog` beneath a {@link ConfirmDialogDefaultsProvider} falls
|
|
38
|
+
* back to when the matching prop is not passed explicitly. Today this is only `cancelLabel` — see
|
|
39
|
+
* that provider's doc comment for why it exists.
|
|
40
|
+
*/
|
|
41
|
+
export interface ConfirmDialogDefaults {
|
|
42
|
+
cancelLabel?: string | undefined;
|
|
43
|
+
}
|
|
44
|
+
export interface ConfirmDialogDefaultsProviderProps extends ConfirmDialogDefaults {
|
|
45
|
+
children: ReactNode;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Publishes host-wide `ConfirmDialog` defaults — today just a translated `cancelLabel` — to every
|
|
49
|
+
* `ConfirmDialog` mounted beneath it. Exists so a host with its own localized "Cancel" copy can
|
|
50
|
+
* set it once at its app root instead of passing `cancelLabel` at every call site (and remembering
|
|
51
|
+
* to add it to every new one it writes later).
|
|
52
|
+
*
|
|
53
|
+
* An explicit `cancelLabel` prop on a given `ConfirmDialog` still wins over this (see
|
|
54
|
+
* {@link useConfirmDialogCancelLabel}). A `ConfirmDialog` mounted with no enclosing provider at
|
|
55
|
+
* all is unaffected — it falls back to the component's own built-in `"Cancel"`, exactly as before
|
|
56
|
+
* this provider existed.
|
|
57
|
+
*
|
|
58
|
+
* Optional by design, unlike `Sidebar`'s `useSidebar` context: a caller with no localization need
|
|
59
|
+
* should never be forced to wrap anything just to render one dialog.
|
|
60
|
+
*/
|
|
61
|
+
export declare function ConfirmDialogDefaultsProvider({ children, cancelLabel }: ConfirmDialogDefaultsProviderProps): import("react").JSX.Element;
|
|
62
|
+
/**
|
|
63
|
+
* Resolves `ConfirmDialog`'s Cancel button text: the explicit `cancelLabel` prop first, then the
|
|
64
|
+
* enclosing {@link ConfirmDialogDefaultsProvider}'s default, then the built-in `"Cancel"`. No
|
|
65
|
+
* provider is a normal, fully-supported state (unlike `useSidebar`, this never throws).
|
|
66
|
+
*
|
|
67
|
+
* @param explicit - The dialog's own `cancelLabel` prop, or `undefined` when the caller passed none.
|
|
68
|
+
* @returns The label to render.
|
|
69
|
+
* @complexity O(1).
|
|
70
|
+
*/
|
|
71
|
+
export declare function useConfirmDialogCancelLabel(explicit: string | undefined): string;
|
|
36
72
|
/**
|
|
37
73
|
* Owns the `<dialog>` element's open/close lifecycle and focus management for `ConfirmDialog`.
|
|
38
74
|
*
|
|
@@ -1,4 +1,45 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext, useEffect, useId, useMemo, useRef, } from 'react';
|
|
3
|
+
/** Empty object, not `undefined` — {@link useConfirmDialogCancelLabel} can always read `cancelLabel`
|
|
4
|
+
* off it without an extra null check, whether or not a provider is mounted. */
|
|
5
|
+
const ConfirmDialogDefaultsContext = createContext({});
|
|
6
|
+
/** The built-in last resort for {@link useConfirmDialogCancelLabel}, used when neither the prop nor
|
|
7
|
+
* an enclosing provider supplies a label. */
|
|
8
|
+
const DEFAULT_CANCEL_LABEL = 'Cancel';
|
|
9
|
+
/**
|
|
10
|
+
* Publishes host-wide `ConfirmDialog` defaults — today just a translated `cancelLabel` — to every
|
|
11
|
+
* `ConfirmDialog` mounted beneath it. Exists so a host with its own localized "Cancel" copy can
|
|
12
|
+
* set it once at its app root instead of passing `cancelLabel` at every call site (and remembering
|
|
13
|
+
* to add it to every new one it writes later).
|
|
14
|
+
*
|
|
15
|
+
* An explicit `cancelLabel` prop on a given `ConfirmDialog` still wins over this (see
|
|
16
|
+
* {@link useConfirmDialogCancelLabel}). A `ConfirmDialog` mounted with no enclosing provider at
|
|
17
|
+
* all is unaffected — it falls back to the component's own built-in `"Cancel"`, exactly as before
|
|
18
|
+
* this provider existed.
|
|
19
|
+
*
|
|
20
|
+
* Optional by design, unlike `Sidebar`'s `useSidebar` context: a caller with no localization need
|
|
21
|
+
* should never be forced to wrap anything just to render one dialog.
|
|
22
|
+
*/
|
|
23
|
+
export function ConfirmDialogDefaultsProvider({ children, cancelLabel }) {
|
|
24
|
+
// Memoized so a host re-render that leaves `cancelLabel` unchanged does not publish a new context
|
|
25
|
+
// value — a fresh object would re-render every `ConfirmDialog` beneath it, even under a memoized
|
|
26
|
+
// parent that otherwise bailed out.
|
|
27
|
+
const defaults = useMemo(() => ({ cancelLabel }), [cancelLabel]);
|
|
28
|
+
return _jsx(ConfirmDialogDefaultsContext.Provider, { value: defaults, children: children });
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Resolves `ConfirmDialog`'s Cancel button text: the explicit `cancelLabel` prop first, then the
|
|
32
|
+
* enclosing {@link ConfirmDialogDefaultsProvider}'s default, then the built-in `"Cancel"`. No
|
|
33
|
+
* provider is a normal, fully-supported state (unlike `useSidebar`, this never throws).
|
|
34
|
+
*
|
|
35
|
+
* @param explicit - The dialog's own `cancelLabel` prop, or `undefined` when the caller passed none.
|
|
36
|
+
* @returns The label to render.
|
|
37
|
+
* @complexity O(1).
|
|
38
|
+
*/
|
|
39
|
+
export function useConfirmDialogCancelLabel(explicit) {
|
|
40
|
+
const { cancelLabel } = useContext(ConfirmDialogDefaultsContext);
|
|
41
|
+
return explicit ?? cancelLabel ?? DEFAULT_CANCEL_LABEL;
|
|
42
|
+
}
|
|
2
43
|
/**
|
|
3
44
|
* Owns the `<dialog>` element's open/close lifecycle and focus management for `ConfirmDialog`.
|
|
4
45
|
*
|
|
@@ -2,8 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import {} from 'react';
|
|
3
3
|
import { agentHandle } from '@jini-ai/agentic';
|
|
4
4
|
import { resolveTone, toneClassName } from '../../types.js';
|
|
5
|
-
import { useConfirmDialog } from './ConfirmDialog.hooks.js';
|
|
6
|
-
const DEFAULT_CANCEL_LABEL = 'Cancel';
|
|
5
|
+
import { useConfirmDialog, useConfirmDialogCancelLabel } from './ConfirmDialog.hooks.js';
|
|
7
6
|
/** Sub-handle segments appended to the caller's base — literals this component chooses itself,
|
|
8
7
|
* never host data (see this file's "Agent handles" doc comment for why that means neither needs
|
|
9
8
|
* sanitizing, unlike `RowMenu`'s per-item keys). */
|
|
@@ -80,7 +79,7 @@ function confirmDialogAgentProps(base, action, options) {
|
|
|
80
79
|
export function ConfirmDialog({ useDialog = useConfirmDialog, agentHandle: baseHandle, ...props }) {
|
|
81
80
|
const { titleId, dialogRef, cancelRef, handleNativeCancel, handleBackdropClick } = useDialog(props.open, props.pending, props.onCancel);
|
|
82
81
|
const tone = resolveTone(props);
|
|
83
|
-
const cancelLabel = props.cancelLabel
|
|
82
|
+
const cancelLabel = useConfirmDialogCancelLabel(props.cancelLabel);
|
|
84
83
|
return (_jsxs("dialog", { ref: dialogRef, className: "confirm-dialog", "aria-labelledby": titleId, onCancel: handleNativeCancel, onClick: handleBackdropClick, children: [_jsx("h2", { id: titleId, children: props.title }), _jsx("div", { className: "confirm-dialog-body", children: props.body }), _jsxs("div", { className: "confirm-dialog-actions", children: [_jsx("button", { ref: cancelRef, type: "button", className: "btn-secondary", disabled: props.pending, onClick: props.onCancel, ...confirmDialogAgentProps(baseHandle, CANCEL_HANDLE_ACTION, {
|
|
85
84
|
role: 'button',
|
|
86
85
|
label: confirmDialogCancelLabel(cancelLabel, props.title),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Fragment, createContext,
|
|
2
|
+
import { Fragment, createContext, useContext, useEffect, useMemo, useRef, useState, } from 'react';
|
|
3
3
|
import { createPortal } from 'react-dom';
|
|
4
4
|
import { DEFAULT_ADMIN_BASE, adminHref } from '../../core/routing/rules.js';
|
|
5
5
|
import { useNavSections } from '../hooks/use-nav-sections.js';
|
|
@@ -18,96 +18,8 @@ export function useSidebar() {
|
|
|
18
18
|
}
|
|
19
19
|
return value;
|
|
20
20
|
}
|
|
21
|
-
/**
|
|
22
|
-
* Shape elements `AdminNavEntry.icon` markup may use. A host draws its own glyphs as raw inner
|
|
23
|
-
* SVG (see that field's doc comment in `core/manifest/types.ts`), so this can't be a fixed set of
|
|
24
|
-
* named icons — but it also means the string reaching {@link Icon} was written by whoever owns the
|
|
25
|
-
* nav entry, which soon enough will be a descriptor rather than code. `g` is included so multi-path
|
|
26
|
-
* icons can group and transform their pieces together.
|
|
27
|
-
*/
|
|
28
|
-
const ICON_ALLOWED_TAGS = new Set(['path', 'circle', 'rect', 'line', 'polygon', 'polyline', 'ellipse', 'g']);
|
|
29
|
-
/**
|
|
30
|
-
* Presentation attributes let through on an icon shape, mapped from their SVG/XML spelling to the
|
|
31
|
-
* camelCase prop name React expects. Anything not listed here — `style`, `href`/`xlink:href`, every
|
|
32
|
-
* `on*` handler — is dropped by {@link sanitizeIconNode} rather than passed through, so there is no
|
|
33
|
-
* allowlist gap to keep in sync with a separate denylist.
|
|
34
|
-
*/
|
|
35
|
-
const ICON_ALLOWED_ATTRS = {
|
|
36
|
-
d: 'd',
|
|
37
|
-
cx: 'cx',
|
|
38
|
-
cy: 'cy',
|
|
39
|
-
r: 'r',
|
|
40
|
-
rx: 'rx',
|
|
41
|
-
ry: 'ry',
|
|
42
|
-
x: 'x',
|
|
43
|
-
y: 'y',
|
|
44
|
-
width: 'width',
|
|
45
|
-
height: 'height',
|
|
46
|
-
x1: 'x1',
|
|
47
|
-
y1: 'y1',
|
|
48
|
-
x2: 'x2',
|
|
49
|
-
y2: 'y2',
|
|
50
|
-
points: 'points',
|
|
51
|
-
transform: 'transform',
|
|
52
|
-
fill: 'fill',
|
|
53
|
-
'fill-rule': 'fillRule',
|
|
54
|
-
opacity: 'opacity',
|
|
55
|
-
'stroke-width': 'strokeWidth',
|
|
56
|
-
'stroke-linecap': 'strokeLinecap',
|
|
57
|
-
'stroke-linejoin': 'strokeLinejoin',
|
|
58
|
-
'clip-rule': 'clipRule',
|
|
59
|
-
};
|
|
60
|
-
/**
|
|
61
|
-
* Rebuilds one parsed element as a React element, keeping only {@link ICON_ALLOWED_TAGS} /
|
|
62
|
-
* {@link ICON_ALLOWED_ATTRS}. This is what stands in for `dangerouslySetInnerHTML`: the browser's
|
|
63
|
-
* own parser does the tokenizing (far less error-prone than a hand-rolled regex over SVG/XML), and
|
|
64
|
-
* this function decides what survives the trip into React's tree — a `<script>`, a `<foreignObject>`
|
|
65
|
-
* carrying arbitrary HTML, an `<image>`/`<use>` reference, or an `onload=` attribute all fail to
|
|
66
|
-
* match anything on either allowlist and are simply not there afterward, whatever they contained.
|
|
67
|
-
*/
|
|
68
|
-
function sanitizeIconNode(node, key) {
|
|
69
|
-
const tag = node.tagName.toLowerCase();
|
|
70
|
-
if (!ICON_ALLOWED_TAGS.has(tag))
|
|
71
|
-
return null;
|
|
72
|
-
// `key` goes straight into the props object — `createElement` pulls it out as the element's
|
|
73
|
-
// reserved key rather than forwarding it to the DOM, the same as writing `key={key}` in JSX.
|
|
74
|
-
const props = { key };
|
|
75
|
-
for (const attr of Array.from(node.attributes)) {
|
|
76
|
-
const propName = ICON_ALLOWED_ATTRS[attr.name.toLowerCase()];
|
|
77
|
-
if (propName)
|
|
78
|
-
props[propName] = attr.value;
|
|
79
|
-
}
|
|
80
|
-
const children = Array.from(node.children)
|
|
81
|
-
.map((child, i) => sanitizeIconNode(child, i))
|
|
82
|
-
.filter((child) => child !== null);
|
|
83
|
-
return createElement(tag, props, children.length ? children : undefined);
|
|
84
|
-
}
|
|
85
|
-
// Reused across parses rather than constructed per render — `DOMParser` instances are stateless
|
|
86
|
-
// and this runs once per icon render, but there is no reason to pay allocation cost for it twice.
|
|
87
|
-
let iconMarkupParser;
|
|
88
|
-
/**
|
|
89
|
-
* Parses one `AdminNavEntry.icon` string into a sanitized element list. Wrapping in a throwaway
|
|
90
|
-
* `<svg>` document (never attached to the page — this is markup parsing, not rendering) lets the
|
|
91
|
-
* browser's own XML parser validate structure for free: malformed markup surfaces as a
|
|
92
|
-
* `parsererror` node, which is treated the same as empty input — the row loses its icon, not its
|
|
93
|
-
* label or link.
|
|
94
|
-
*/
|
|
95
|
-
function parseIconMarkup(markup) {
|
|
96
|
-
if (!markup)
|
|
97
|
-
return [];
|
|
98
|
-
iconMarkupParser ??= new DOMParser();
|
|
99
|
-
const doc = iconMarkupParser.parseFromString(`<svg xmlns="http://www.w3.org/2000/svg">${markup}</svg>`, 'image/svg+xml');
|
|
100
|
-
if (doc.getElementsByTagName('parsererror').length > 0)
|
|
101
|
-
return [];
|
|
102
|
-
return Array.from(doc.documentElement.children)
|
|
103
|
-
.map((child, i) => sanitizeIconNode(child, i))
|
|
104
|
-
.filter((child) => child !== null);
|
|
105
|
-
}
|
|
106
21
|
function Icon(props) {
|
|
107
|
-
|
|
108
|
-
// that, in practice, never changes after the nav manifest is built.
|
|
109
|
-
const children = useMemo(() => parseIconMarkup(props.markup), [props.markup]);
|
|
110
|
-
return (_jsx("svg", { viewBox: "0 0 18 18", fill: "none", stroke: "currentColor", strokeWidth: 1.5, children: children }));
|
|
22
|
+
return (_jsx("svg", { viewBox: "0 0 18 18", fill: "none", stroke: "currentColor", strokeWidth: 1.5, dangerouslySetInnerHTML: { __html: props.markup } }));
|
|
111
23
|
}
|
|
112
24
|
/**
|
|
113
25
|
* Rail-mode tooltip, portaled to `document.body`.
|
package/dist/react/index.d.ts
CHANGED
|
@@ -38,8 +38,10 @@ export type { ConfirmButtonProps } from './components/ConfirmButton/ConfirmButto
|
|
|
38
38
|
export { ConfirmDialog } from './components/ConfirmDialog/ConfirmDialog.js';
|
|
39
39
|
export type { ConfirmDialogProps } from './components/ConfirmDialog/ConfirmDialog.js';
|
|
40
40
|
export type { ConfirmDialogController, UseConfirmDialog } from './components/ConfirmDialog/ConfirmDialog.hooks.js';
|
|
41
|
+
export { ConfirmDialogDefaultsProvider } from './components/ConfirmDialog/ConfirmDialog.hooks.js';
|
|
42
|
+
export type { ConfirmDialogDefaults, ConfirmDialogDefaultsProviderProps, } from './components/ConfirmDialog/ConfirmDialog.hooks.js';
|
|
41
43
|
export { DataTable } from './components/DataTable.js';
|
|
42
|
-
export type { DataTableColumn,
|
|
44
|
+
export type { DataTableColumn, DataTableProps } from './components/DataTable.js';
|
|
43
45
|
export { InteractiveHtmlEditor } from './components/InteractiveHtmlEditor/InteractiveHtmlEditor.js';
|
|
44
46
|
export type { InteractiveHtmlEditorProps } from './components/InteractiveHtmlEditor/InteractiveHtmlEditor.js';
|
|
45
47
|
export { RowMenu } from './components/RowMenu/RowMenu.js';
|
package/dist/react/index.js
CHANGED
|
@@ -36,9 +36,11 @@
|
|
|
36
36
|
export { resolveTone, toneClassName } from './types.js';
|
|
37
37
|
export { ConfirmButton } from './components/ConfirmButton/ConfirmButton.js';
|
|
38
38
|
export { ConfirmDialog } from './components/ConfirmDialog/ConfirmDialog.js';
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
|
|
39
|
+
// Host-wide `ConfirmDialog` defaults (today just a translated `cancelLabel`), set once at an app
|
|
40
|
+
// root rather than passed at every call site — see `ConfirmDialogDefaultsProvider`'s doc comment.
|
|
41
|
+
export { ConfirmDialogDefaultsProvider } from './components/ConfirmDialog/ConfirmDialog.hooks.js';
|
|
42
|
+
// The list table. Deliberately has no sorting, pagination or row selection — see its file header
|
|
43
|
+
// for the corpus evidence behind each omission.
|
|
42
44
|
export { DataTable } from './components/DataTable.js';
|
|
43
45
|
// Visual click-into-text editing surface for a bespoke HTML document, built on GrapesJS. See its
|
|
44
46
|
// own file header for the styling-contract exception it carries (vendor CSS import) and the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jini-ai/admin",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.9",
|
|
4
4
|
"description": "Composable admin surface for Jini-hosted products: framework-free contracts, panel registry, and route model in `/core`; React shell and panels in `/react`. Import only the layers you need.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
"!dist/**/*.test.d.ts",
|
|
52
52
|
"!dist/**/*.test.js.map",
|
|
53
53
|
"!dist/**/*.test.d.ts.map",
|
|
54
|
-
"!dist/**/__tests__/**"
|
|
54
|
+
"!dist/**/__tests__/**",
|
|
55
|
+
"!dist/**/*.map"
|
|
55
56
|
],
|
|
56
57
|
"publishConfig": {
|
|
57
58
|
"access": "public",
|
|
@@ -80,8 +81,8 @@
|
|
|
80
81
|
"react-dom": "^19.2.0"
|
|
81
82
|
},
|
|
82
83
|
"dependencies": {
|
|
83
|
-
"@jini-ai/agentic": "0.3.
|
|
84
|
-
"@jini-ai/ui": "0.3.
|
|
84
|
+
"@jini-ai/agentic": "0.3.0",
|
|
85
|
+
"@jini-ai/ui": "0.3.9"
|
|
85
86
|
},
|
|
86
87
|
"scripts": {
|
|
87
88
|
"build": "tsc -p tsconfig.json",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,gBAAgB,EAChB,8BAA8B,EAC9B,QAAQ,EACR,aAAa,EACb,gBAAgB,GACjB,MAAM,iBAAiB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/browser/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,gBAAgB,EAChB,8BAA8B,EAC9B,QAAQ,EACR,aAAa,EACb,gBAAgB,GACjB,MAAM,iBAAiB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/browser/navigation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,iGAAiG;AACjG,eAAO,MAAM,gBAAgB,wBAAwB,CAAC;AAEtD,yDAAyD;AACzD,wBAAgB,aAAa,CAAC,IAAI,GAAE,MAA2B,GAAG,MAAM,CAEvE;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GACnE,IAAI,CA8BN;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,GAAE,MAA2B,GAAG,MAAM,IAAI,CAiC5F;AAED,sFAAsF;AACtF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAOjE"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../src/browser/navigation.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/data-table/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,sBAAsB,GAAG,KAAK,GAAG,MAAM,CAAC;AAEpD;oFACoF;AACpF,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,sBAAsB,CAAC;CACnC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/data-table/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file The runtime half of `AdminEntityPort`: registration, descriptor validation, and the one
|
|
3
|
-
* erasure a screen generic over all entities needs.
|
|
4
|
-
*
|
|
5
|
-
* `core/ports/entities.ts` is types only, like every other port. Everything here is the code those
|
|
6
|
-
* types cannot be: checks that a descriptor is internally consistent, and the single cast that
|
|
7
|
-
* turns a descriptor-generic port into the shape a screen can hold.
|
|
8
|
-
*
|
|
9
|
-
* ## Why any of this is runtime rather than type-level
|
|
10
|
-
*
|
|
11
|
-
* Two of the descriptor's own promises are not expressible in the type system:
|
|
12
|
-
*
|
|
13
|
-
* - `titleField` names a `text` field on this same descriptor. Encoding that needs a conditional
|
|
14
|
-
* type heavy enough to make every descriptor's error message unreadable — and a typo here is not
|
|
15
|
-
* cosmetic: it makes every relation picker pointing at this entity render `undefined` for every
|
|
16
|
-
* row, which looks like missing data rather than a typo.
|
|
17
|
-
* - `relation.target` names another *registered* entity. A descriptor cannot know what it will be
|
|
18
|
-
* registered beside, so this can only be checked once the registry is assembled.
|
|
19
|
-
*
|
|
20
|
-
* Both are therefore checked at composition time, where they fail once, at startup, naming the
|
|
21
|
-
* problem — rather than at render time, silently, as blank cells.
|
|
22
|
-
*/
|
|
23
|
-
import type { AdminEntityDescriptor, AdminEntityField, AdminEntityPort, AdminEntityRegistry, AdminErasedEntityPort } from '../ports/entities.js';
|
|
24
|
-
/**
|
|
25
|
-
* A row that does not match the descriptor its port advertises.
|
|
26
|
-
*
|
|
27
|
-
* This is the failure `eraseEntityPort`'s cast makes possible: the cast is sound in the direction
|
|
28
|
-
* that matters (a typed row *is* a bag of unknowns), and unsound only if an adapter lies about its
|
|
29
|
-
* own descriptor. Nothing in the type system catches that, so this is what does — as a report, not
|
|
30
|
-
* an exception: a mistyped field is a fidelity problem, and throwing on a read would take a
|
|
31
|
-
* mostly-working screen down over one bad cell.
|
|
32
|
-
*/
|
|
33
|
-
export interface AdminEntityRowViolation {
|
|
34
|
-
/** `descriptor.name` of the port that produced the row. */
|
|
35
|
-
readonly entity: string;
|
|
36
|
-
readonly operation: 'list' | 'get' | 'create' | 'update';
|
|
37
|
-
/** The offending row's `id`, or `'<no id>'` when that is itself what is wrong. */
|
|
38
|
-
readonly rowId: string;
|
|
39
|
-
/** Declared field name, `'id'`, or the undeclared key that appeared. */
|
|
40
|
-
readonly field: string;
|
|
41
|
-
readonly problem: 'missing-required' | 'wrong-type' | 'undeclared-field';
|
|
42
|
-
/** One sentence naming what was expected and what arrived. Safe to log verbatim. */
|
|
43
|
-
readonly detail: string;
|
|
44
|
-
}
|
|
45
|
-
export interface AdminEntityErasureOptions {
|
|
46
|
-
/**
|
|
47
|
-
* Where descriptor-conformance violations are reported.
|
|
48
|
-
*
|
|
49
|
-
* **Omit it and no row checking runs at all** — that is the zero-cost default, and it is why this
|
|
50
|
-
* package emits no diagnostics of its own (nothing here writes to `console`; a host owns its
|
|
51
|
-
* reporting the same way it owns its transport). A host wires this under its own development
|
|
52
|
-
* flag and gets adapter drift surfaced the moment it happens; production pays nothing.
|
|
53
|
-
*/
|
|
54
|
-
readonly onViolation?: (violation: AdminEntityRowViolation) => void;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Whether `value` is a legal runtime value for `field`.
|
|
58
|
-
*
|
|
59
|
-
* Exported because an EDITOR needs exactly this judgement and must not re-derive it. A generic form
|
|
60
|
-
* that decides for itself what an `integer` accepts will drift from what the conformance walk
|
|
61
|
-
* below rejects, and the two disagreeing is worse than either being wrong alone: the form saves a
|
|
62
|
-
* value the port then reports as a violation, so the write succeeds and the diagnostic blames the
|
|
63
|
-
* adapter. `1.5` in an `integer` and `Infinity` in a `real` are both reachable from a plain
|
|
64
|
-
* `<input type="number">` — `step` constrains the spinner, not the parsed value — so this is not a
|
|
65
|
-
* theoretical seam. One function, both callers.
|
|
66
|
-
*
|
|
67
|
-
* @param field The declared field the value is destined for.
|
|
68
|
-
* @param value The candidate value, typically a form draft entry or an adapter-returned cell.
|
|
69
|
-
* @returns `null` when it conforms, otherwise a one-phrase reason naming what arrived instead.
|
|
70
|
-
* Phrased to complete the sentence "declared `<kind>`; ...".
|
|
71
|
-
* @complexity Time O(1) for every kind but `json`; see {@link describeNonJsonValue} for that one.
|
|
72
|
-
* @overallScore 100
|
|
73
|
-
*/
|
|
74
|
-
export declare function describeAdminEntityFieldMismatch(field: AdminEntityField, value: unknown): string | null;
|
|
75
|
-
/**
|
|
76
|
-
* Erases a port's descriptor generic so a screen can hold ports for different entities in one
|
|
77
|
-
* collection.
|
|
78
|
-
*
|
|
79
|
-
* The `as unknown as` below is unavoidable and is the only one in this port. `create` and `update`
|
|
80
|
-
* take the row type as a *parameter*, so `AdminEntityPort<SpecificDescriptor>` is contravariant in
|
|
81
|
-
* it and is genuinely not assignable to any common supertype. The cast is sound in the direction
|
|
82
|
-
* that gets exercised — a typed row is a bag of unknowns — and unsound only if the adapter's rows
|
|
83
|
-
* do not match the descriptor it advertises, which is precisely what `options.onViolation` is here
|
|
84
|
-
* to surface.
|
|
85
|
-
*
|
|
86
|
-
* @param port A port whose rows are typed by its own descriptor.
|
|
87
|
-
* @param options Wire `onViolation` to have every row checked against the descriptor on the way
|
|
88
|
-
* out; omit it for zero added cost.
|
|
89
|
-
* @returns The same port, typed as {@link AdminErasedEntityPort}; a fresh wrapper object when
|
|
90
|
-
* `onViolation` is set, and the original object when it is not.
|
|
91
|
-
* @complexity Time O(1) to erase; O(rows × fields) per call when checking is on.
|
|
92
|
-
* @overallScore 100
|
|
93
|
-
*/
|
|
94
|
-
export declare function eraseEntityPort<D extends AdminEntityDescriptor>(port: AdminEntityPort<D>, options?: AdminEntityErasureOptions): AdminErasedEntityPort;
|
|
95
|
-
/**
|
|
96
|
-
* Assembles entity ports into a registry, validating every descriptor first.
|
|
97
|
-
*
|
|
98
|
-
* Same ergonomics as `createAdminClient`: one object literal, `TPorts` inferred, host-owned and
|
|
99
|
-
* Jini-shipped entries indistinguishable. Registering an entity is one line.
|
|
100
|
-
*
|
|
101
|
-
* **No key is reserved.** `createAdminClient` reserves `'transport'` because it merges the
|
|
102
|
-
* transport into the same object it returns; this returns nothing but the ports, so there is
|
|
103
|
-
* nothing an entity named `transport` could shadow. The returned object has a `null` prototype, so
|
|
104
|
-
* a lookup by an attacker- or URL-supplied name (`'constructor'`, `'__proto__'`) resolves to
|
|
105
|
-
* `undefined` rather than walking to `Object.prototype` and yielding a truthy non-port.
|
|
106
|
-
*
|
|
107
|
-
* Deliberately takes no erasure options: a registry holds ports with their row types intact, and
|
|
108
|
-
* checking only becomes possible once those types are erased. `onViolation` therefore belongs to
|
|
109
|
-
* {@link getErasedEntityPort}/{@link listErasedEntityPorts}, at the point the guarantee is dropped.
|
|
110
|
-
*
|
|
111
|
-
* @param ports Entity name -> port. Each key must equal that port's `descriptor.name`.
|
|
112
|
-
* @returns A frozen, null-prototype registry preserving each port's own type.
|
|
113
|
-
* @throws {Error} listing *every* problem found, not just the first — a descriptor with three
|
|
114
|
-
* typos should take one round trip to fix, not three.
|
|
115
|
-
* @complexity Time O(entities × fields); space O(entities).
|
|
116
|
-
* @overallScore 100
|
|
117
|
-
*/
|
|
118
|
-
export declare function createAdminEntityRegistry<TPorts extends Record<string, AdminEntityPort<AdminEntityDescriptor>>>(ports: TPorts): AdminEntityRegistry<TPorts>;
|
|
119
|
-
/**
|
|
120
|
-
* Every registered port, erased, in registration order — what a screen that renders any entity
|
|
121
|
-
* iterates.
|
|
122
|
-
*
|
|
123
|
-
* @complexity Time O(entities); space O(entities).
|
|
124
|
-
* @overallScore 100
|
|
125
|
-
*/
|
|
126
|
-
export declare function listErasedEntityPorts(registry: Readonly<Record<string, AdminEntityPort<AdminEntityDescriptor>>>, options?: AdminEntityErasureOptions): readonly AdminErasedEntityPort[];
|
|
127
|
-
/**
|
|
128
|
-
* The erased port registered under `name`, or `null`.
|
|
129
|
-
*
|
|
130
|
-
* `name` is routinely a URL segment, so this never trusts a bare property read: the registry's null
|
|
131
|
-
* prototype already stops `'constructor'` resolving to something truthy, and `Object.hasOwn` holds
|
|
132
|
-
* that guarantee even for a caller that hands in a plain object literal instead.
|
|
133
|
-
*
|
|
134
|
-
* @complexity Time O(1) for the lookup, O(1) for the erasure.
|
|
135
|
-
* @overallScore 100
|
|
136
|
-
*/
|
|
137
|
-
export declare function getErasedEntityPort(registry: Readonly<Record<string, AdminEntityPort<AdminEntityDescriptor>>>, name: string, options?: AdminEntityErasureOptions): AdminErasedEntityPort | null;
|
|
138
|
-
//# sourceMappingURL=rules.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../../src/core/entities/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EACV,qBAAqB,EACrB,gBAAgB,EAGhB,eAAe,EACf,mBAAmB,EAEnB,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAW9B;;;;;;;;GAQG;AACH,MAAM,WAAW,uBAAuB;IACtC,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACzD,kFAAkF;IAClF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,kBAAkB,GAAG,YAAY,GAAG,kBAAkB,CAAC;IACzE,oFAAoF;IACpF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,yBAAyB;IACxC;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,uBAAuB,KAAK,IAAI,CAAC;CACrE;AA8CD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,OAAO,GACb,MAAM,GAAG,IAAI,CAuBf;AAyED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,qBAAqB,EAC7D,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,EACxB,OAAO,GAAE,yBAA8B,GACtC,qBAAqB,CAgCvB;AA4DD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,qBAAqB,CAAC,CAAC,EACrE,KAAK,EAAE,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAc5C;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAC1E,OAAO,GAAE,yBAA8B,GACtC,SAAS,qBAAqB,EAAE,CAElC;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAC1E,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,yBAA8B,GACtC,qBAAqB,GAAG,IAAI,CAI9B"}
|