@jini-ai/admin 0.3.0 → 0.3.6
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/README.md +7 -4
- package/dist/core/data-table/types.d.ts +14 -0
- package/dist/core/data-table/types.d.ts.map +1 -0
- package/dist/core/data-table/types.js +8 -0
- package/dist/core/data-table/types.js.map +1 -0
- package/dist/core/entities/rules.d.ts +138 -0
- package/dist/core/entities/rules.d.ts.map +1 -0
- package/dist/core/entities/rules.js +344 -0
- package/dist/core/entities/rules.js.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/ports/entities.d.ts +302 -0
- package/dist/core/ports/entities.d.ts.map +1 -0
- package/dist/core/ports/entities.js +47 -0
- package/dist/core/ports/entities.js.map +1 -0
- package/dist/core/ports/index.d.ts +1 -0
- package/dist/core/ports/index.d.ts.map +1 -1
- package/dist/core/ports/menus.d.ts +43 -0
- package/dist/core/ports/menus.d.ts.map +1 -1
- package/dist/core/ports/menus.js +43 -0
- package/dist/core/ports/menus.js.map +1 -1
- package/dist/react/components/DataTable.d.ts +70 -8
- package/dist/react/components/DataTable.d.ts.map +1 -1
- package/dist/react/components/DataTable.js +58 -2
- package/dist/react/components/DataTable.js.map +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +3 -2
- package/dist/react/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ not in your bundle.
|
|
|
18
18
|
| `@jini-ai/admin/core` | contracts, panel registry, route matching, transport, ports | nothing |
|
|
19
19
|
| `@jini-ai/admin/browser` | `window`-bound navigation, link interception | a DOM |
|
|
20
20
|
| `@jini-ai/admin/server` | Composio integration: catalog, OAuth, tool execution | Node.js |
|
|
21
|
-
| `@jini-ai/admin/react`
|
|
21
|
+
| `@jini-ai/admin/react` | Presentational primitives (`Sidebar`, `DataTable`, `RowMenu`, `ConfirmButton`, `ConfirmDialog`, `InteractiveHtmlEditor`) and hooks; `<AdminShell>` and panels are not built yet | React (optional peer) |
|
|
22
22
|
|
|
23
23
|
`/core` is the layer a panel author codes against: no React, no DOM, no I/O. That boundary is
|
|
24
24
|
enforced at runtime — this package's vitest config runs `src/core/**` without a jsdom environment,
|
|
@@ -133,6 +133,9 @@ unrelated domain features to get a type.
|
|
|
133
133
|
|
|
134
134
|
## Status
|
|
135
135
|
|
|
136
|
-
Slice 1: `/core` and `/browser
|
|
137
|
-
to `@jini-ai/integrations/composio`) no longer exists in this package.
|
|
138
|
-
|
|
136
|
+
Slice 1: `/core` (75 tests) and `/browser` (no test files). `/server` (Composio, folded in
|
|
137
|
+
2026-08-01, moved back out to `@jini-ai/integrations/composio`) no longer exists in this package.
|
|
138
|
+
`/react` has real content — presentational primitives and hooks (147 tests) — but no `<AdminShell>`
|
|
139
|
+
or panels yet. `src/core/ports/` now specifies 16 ports (`identity`, `menus`, `integrations`,
|
|
140
|
+
`workspace`, `redirects`, `analytics`, `settings`, `forms`, `seo`, `database`, `members`,
|
|
141
|
+
`recovery`, `auth`, `media`, `plugins`, `comments`), not just `AdminIdentityPort`.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Sort state for `@jini-ai/admin/react`'s `DataTable`. Plain data — no React, no DOM — so a
|
|
3
|
+
* panel can hold and pass this shape (e.g. as component state) without pulling in the React layer
|
|
4
|
+
* just for a type. `DataTable.tsx` imports and re-exports these for its own consumers; this file is
|
|
5
|
+
* the single source of truth.
|
|
6
|
+
*/
|
|
7
|
+
export type DataTableSortDirection = 'asc' | 'desc';
|
|
8
|
+
/** Controlled sort state: the active column's `key` plus its direction. See `sort`/`onSortChange`
|
|
9
|
+
* on `DataTableProps` in `DataTable.tsx` — `DataTable` never holds this itself. */
|
|
10
|
+
export interface DataTableSortState {
|
|
11
|
+
column: string;
|
|
12
|
+
direction: DataTableSortDirection;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Sort state for `@jini-ai/admin/react`'s `DataTable`. Plain data — no React, no DOM — so a
|
|
3
|
+
* panel can hold and pass this shape (e.g. as component state) without pulling in the React layer
|
|
4
|
+
* just for a type. `DataTable.tsx` imports and re-exports these for its own consumers; this file is
|
|
5
|
+
* the single source of truth.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/data-table/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,138 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,344 @@
|
|
|
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
|
+
/** Row keys are never declared as fields — every row carries one implicitly. */
|
|
24
|
+
const IMPLICIT_ROW_KEY = 'id';
|
|
25
|
+
/** Bounds on the `json` conformance walk. Sized like `MAX_FIELD_DEFS` in `@jini-ai/cms`: large
|
|
26
|
+
* enough that no honest payload hits them, small enough that a cyclic or adversarial value fails
|
|
27
|
+
* fast instead of hanging a render. */
|
|
28
|
+
const MAX_JSON_DEPTH = 32;
|
|
29
|
+
const MAX_JSON_NODES = 10_000;
|
|
30
|
+
/**
|
|
31
|
+
* Whether `value` is a JSON value: `null`, a boolean, a *finite* number, a string, an array of
|
|
32
|
+
* them, or a plain object of them.
|
|
33
|
+
*
|
|
34
|
+
* Bounded by {@link MAX_JSON_DEPTH}/{@link MAX_JSON_NODES}, which also makes it terminate on a
|
|
35
|
+
* cyclic value rather than recursing forever. "Storage-only" means not indexed — it does not mean
|
|
36
|
+
* not checked: a validator that returns true for everything is not a validator, and the values it
|
|
37
|
+
* would wave through (functions, `BigInt`, `undefined`, `NaN`, cycles) are exactly the ones that
|
|
38
|
+
* throw or silently vanish at the `JSON.stringify` boundary downstream of it.
|
|
39
|
+
*
|
|
40
|
+
* @returns `null` when the value conforms, otherwise a one-phrase reason.
|
|
41
|
+
* @complexity Time O(nodes) bounded by {@link MAX_JSON_NODES}; space O(depth) bounded by
|
|
42
|
+
* {@link MAX_JSON_DEPTH}.
|
|
43
|
+
* @overallScore 100
|
|
44
|
+
*/
|
|
45
|
+
function describeNonJsonValue(value, depth = 0, budget = { nodes: 0 }) {
|
|
46
|
+
if (depth > MAX_JSON_DEPTH)
|
|
47
|
+
return `nests deeper than ${MAX_JSON_DEPTH} levels`;
|
|
48
|
+
if (++budget.nodes > MAX_JSON_NODES)
|
|
49
|
+
return `holds more than ${MAX_JSON_NODES} values`;
|
|
50
|
+
if (value === null)
|
|
51
|
+
return null;
|
|
52
|
+
const type = typeof value;
|
|
53
|
+
if (type === 'string' || type === 'boolean')
|
|
54
|
+
return null;
|
|
55
|
+
if (type === 'number')
|
|
56
|
+
return Number.isFinite(value) ? null : 'is a non-finite number';
|
|
57
|
+
if (type !== 'object')
|
|
58
|
+
return `is a ${type}`;
|
|
59
|
+
if (Array.isArray(value)) {
|
|
60
|
+
for (const item of value) {
|
|
61
|
+
const reason = describeNonJsonValue(item, depth + 1, budget);
|
|
62
|
+
if (reason !== null)
|
|
63
|
+
return reason;
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
// Rejects class instances, `Map`, `Date`, and anything else that survives `typeof === 'object'`
|
|
68
|
+
// but does not round-trip through JSON as itself.
|
|
69
|
+
const proto = Object.getPrototypeOf(value);
|
|
70
|
+
if (proto !== Object.prototype && proto !== null)
|
|
71
|
+
return 'is a non-plain object';
|
|
72
|
+
for (const item of Object.values(value)) {
|
|
73
|
+
const reason = describeNonJsonValue(item, depth + 1, budget);
|
|
74
|
+
if (reason !== null)
|
|
75
|
+
return reason;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Whether `value` is a legal runtime value for `field`.
|
|
81
|
+
*
|
|
82
|
+
* Exported because an EDITOR needs exactly this judgement and must not re-derive it. A generic form
|
|
83
|
+
* that decides for itself what an `integer` accepts will drift from what the conformance walk
|
|
84
|
+
* below rejects, and the two disagreeing is worse than either being wrong alone: the form saves a
|
|
85
|
+
* value the port then reports as a violation, so the write succeeds and the diagnostic blames the
|
|
86
|
+
* adapter. `1.5` in an `integer` and `Infinity` in a `real` are both reachable from a plain
|
|
87
|
+
* `<input type="number">` — `step` constrains the spinner, not the parsed value — so this is not a
|
|
88
|
+
* theoretical seam. One function, both callers.
|
|
89
|
+
*
|
|
90
|
+
* @param field The declared field the value is destined for.
|
|
91
|
+
* @param value The candidate value, typically a form draft entry or an adapter-returned cell.
|
|
92
|
+
* @returns `null` when it conforms, otherwise a one-phrase reason naming what arrived instead.
|
|
93
|
+
* Phrased to complete the sentence "declared `<kind>`; ...".
|
|
94
|
+
* @complexity Time O(1) for every kind but `json`; see {@link describeNonJsonValue} for that one.
|
|
95
|
+
* @overallScore 100
|
|
96
|
+
*/
|
|
97
|
+
export function describeAdminEntityFieldMismatch(field, value) {
|
|
98
|
+
switch (field.kind) {
|
|
99
|
+
case 'text':
|
|
100
|
+
case 'relation':
|
|
101
|
+
return typeof value === 'string' ? null : `expected a string, got ${typeof value}`;
|
|
102
|
+
case 'datetime':
|
|
103
|
+
if (typeof value !== 'string')
|
|
104
|
+
return `expected an ISO-8601 string, got ${typeof value}`;
|
|
105
|
+
// A `datetime` that is not parseable renders fine and orders wrongly — the exact class of
|
|
106
|
+
// fault this whole check exists for, so it is a mismatch rather than a pass.
|
|
107
|
+
return Number.isNaN(Date.parse(value)) ? 'is not a parseable ISO-8601 timestamp' : null;
|
|
108
|
+
case 'integer':
|
|
109
|
+
if (typeof value !== 'number')
|
|
110
|
+
return `expected a number, got ${typeof value}`;
|
|
111
|
+
return Number.isInteger(value) ? null : 'is not an integer';
|
|
112
|
+
case 'real':
|
|
113
|
+
if (typeof value !== 'number')
|
|
114
|
+
return `expected a number, got ${typeof value}`;
|
|
115
|
+
return Number.isFinite(value) ? null : 'is not a finite number';
|
|
116
|
+
case 'boolean':
|
|
117
|
+
return typeof value === 'boolean' ? null : `expected a boolean, got ${typeof value}`;
|
|
118
|
+
case 'json': {
|
|
119
|
+
const reason = describeNonJsonValue(value);
|
|
120
|
+
return reason === null ? null : `is not a JSON value: it ${reason}`;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Every way `row` fails to match `descriptor`.
|
|
126
|
+
*
|
|
127
|
+
* Reports undeclared keys as well as missing and mistyped ones: a key the descriptor does not
|
|
128
|
+
* mention is invisible to a generic screen, so an adapter growing a field without declaring it
|
|
129
|
+
* shows up as data that exists and never renders — which reads as a screen bug rather than a
|
|
130
|
+
* descriptor gap.
|
|
131
|
+
*
|
|
132
|
+
* @complexity Time O(fields + row keys) plus the `json` walk; space O(violations).
|
|
133
|
+
* @overallScore 100
|
|
134
|
+
*/
|
|
135
|
+
function findRowViolations(descriptor, operation, row) {
|
|
136
|
+
const found = [];
|
|
137
|
+
const rowId = typeof row.id === 'string' && row.id !== '' ? row.id : '<no id>';
|
|
138
|
+
const push = (field, problem, detail) => {
|
|
139
|
+
found.push({ entity: descriptor.name, operation, rowId, field, problem, detail });
|
|
140
|
+
};
|
|
141
|
+
if (typeof row.id !== 'string' || row.id === '') {
|
|
142
|
+
push(IMPLICIT_ROW_KEY, 'wrong-type', 'every row must carry a non-empty string `id`');
|
|
143
|
+
}
|
|
144
|
+
const declared = new Set([IMPLICIT_ROW_KEY]);
|
|
145
|
+
for (const field of descriptor.fields) {
|
|
146
|
+
declared.add(field.name);
|
|
147
|
+
const value = row[field.name];
|
|
148
|
+
if (value === undefined) {
|
|
149
|
+
if (field.required === true) {
|
|
150
|
+
push(field.name, 'missing-required', 'declared `required: true` but absent from the row');
|
|
151
|
+
}
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
const mismatch = describeAdminEntityFieldMismatch(field, value);
|
|
155
|
+
if (mismatch !== null)
|
|
156
|
+
push(field.name, 'wrong-type', `declared \`${field.kind}\`; ${mismatch}`);
|
|
157
|
+
}
|
|
158
|
+
for (const key of Object.keys(row)) {
|
|
159
|
+
if (declared.has(key))
|
|
160
|
+
continue;
|
|
161
|
+
push(key, 'undeclared-field', 'present on the row but not declared on the descriptor');
|
|
162
|
+
}
|
|
163
|
+
return found;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Runs `row` past its descriptor and reports anything wrong, then returns it unchanged.
|
|
167
|
+
*
|
|
168
|
+
* Deliberately identity-returning: this is an observation point, never a repair point. Coercing a
|
|
169
|
+
* bad value here would hide the adapter bug it exists to expose.
|
|
170
|
+
*
|
|
171
|
+
* @complexity Time O(rows × fields); no-op and O(1) when `onViolation` is absent.
|
|
172
|
+
* @overallScore 100
|
|
173
|
+
*/
|
|
174
|
+
function checkRow(descriptor, operation, row, onViolation) {
|
|
175
|
+
if (onViolation === undefined)
|
|
176
|
+
return row;
|
|
177
|
+
for (const violation of findRowViolations(descriptor, operation, row))
|
|
178
|
+
onViolation(violation);
|
|
179
|
+
return row;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Erases a port's descriptor generic so a screen can hold ports for different entities in one
|
|
183
|
+
* collection.
|
|
184
|
+
*
|
|
185
|
+
* The `as unknown as` below is unavoidable and is the only one in this port. `create` and `update`
|
|
186
|
+
* take the row type as a *parameter*, so `AdminEntityPort<SpecificDescriptor>` is contravariant in
|
|
187
|
+
* it and is genuinely not assignable to any common supertype. The cast is sound in the direction
|
|
188
|
+
* that gets exercised — a typed row is a bag of unknowns — and unsound only if the adapter's rows
|
|
189
|
+
* do not match the descriptor it advertises, which is precisely what `options.onViolation` is here
|
|
190
|
+
* to surface.
|
|
191
|
+
*
|
|
192
|
+
* @param port A port whose rows are typed by its own descriptor.
|
|
193
|
+
* @param options Wire `onViolation` to have every row checked against the descriptor on the way
|
|
194
|
+
* out; omit it for zero added cost.
|
|
195
|
+
* @returns The same port, typed as {@link AdminErasedEntityPort}; a fresh wrapper object when
|
|
196
|
+
* `onViolation` is set, and the original object when it is not.
|
|
197
|
+
* @complexity Time O(1) to erase; O(rows × fields) per call when checking is on.
|
|
198
|
+
* @overallScore 100
|
|
199
|
+
*/
|
|
200
|
+
export function eraseEntityPort(port, options = {}) {
|
|
201
|
+
const erased = port;
|
|
202
|
+
const { onViolation } = options;
|
|
203
|
+
if (onViolation === undefined)
|
|
204
|
+
return erased;
|
|
205
|
+
const { descriptor } = port;
|
|
206
|
+
const checked = {
|
|
207
|
+
descriptor,
|
|
208
|
+
async list(query) {
|
|
209
|
+
const page = await erased.list(query);
|
|
210
|
+
for (const row of page.items)
|
|
211
|
+
checkRow(descriptor, 'list', row, onViolation);
|
|
212
|
+
return page;
|
|
213
|
+
},
|
|
214
|
+
async get(id) {
|
|
215
|
+
const row = await erased.get(id);
|
|
216
|
+
return row === null ? null : checkRow(descriptor, 'get', row, onViolation);
|
|
217
|
+
},
|
|
218
|
+
async create(input) {
|
|
219
|
+
return checkRow(descriptor, 'create', await erased.create(input), onViolation);
|
|
220
|
+
},
|
|
221
|
+
async update(id, patch) {
|
|
222
|
+
return checkRow(descriptor, 'update', await erased.update(id, patch), onViolation);
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
// Preserved by presence, not by a forwarding stub: a screen decides whether to render a delete
|
|
226
|
+
// affordance by testing `remove !== undefined`, so wrapping an absent one into an always-present
|
|
227
|
+
// function would give every entity a delete button that throws.
|
|
228
|
+
const { remove } = erased;
|
|
229
|
+
if (remove === undefined)
|
|
230
|
+
return checked;
|
|
231
|
+
// `.call(erased, ...)` rather than a bare reference: an adapter written as an object literal with
|
|
232
|
+
// shorthand methods may legitimately use `this` to reach its own store.
|
|
233
|
+
return { ...checked, remove: (id) => remove.call(erased, id) };
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Every internal inconsistency in one descriptor, as human-readable sentences.
|
|
237
|
+
*
|
|
238
|
+
* @param descriptor The descriptor to check.
|
|
239
|
+
* @param registryKey The key it is being registered under.
|
|
240
|
+
* @param registeredNames Every name in the registry, for resolving `relation` targets.
|
|
241
|
+
* @complexity Time O(fields); space O(problems).
|
|
242
|
+
* @overallScore 100
|
|
243
|
+
*/
|
|
244
|
+
function findDescriptorProblems(descriptor, registryKey, registeredNames) {
|
|
245
|
+
const problems = [];
|
|
246
|
+
const at = `'${registryKey}'`;
|
|
247
|
+
if (descriptor.name !== registryKey) {
|
|
248
|
+
// One entity, one name. Allowing these to differ would leave the URL segment, the relation
|
|
249
|
+
// target, and the registry key as three identifiers with no stated relationship between them.
|
|
250
|
+
problems.push(`${at}: registered under '${registryKey}' but its descriptor is named '${descriptor.name}'`);
|
|
251
|
+
}
|
|
252
|
+
if (descriptor.labelSingular === '' || descriptor.labelPlural === '') {
|
|
253
|
+
problems.push(`${at}: labelSingular and labelPlural must both be non-empty`);
|
|
254
|
+
}
|
|
255
|
+
if (descriptor.fields.length === 0) {
|
|
256
|
+
problems.push(`${at}: declares no fields, so nothing but its id could ever be shown or edited`);
|
|
257
|
+
}
|
|
258
|
+
const seen = new Set();
|
|
259
|
+
for (const field of descriptor.fields) {
|
|
260
|
+
if (field.name === '') {
|
|
261
|
+
problems.push(`${at}: a field has an empty name`);
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
if (field.name === IMPLICIT_ROW_KEY) {
|
|
265
|
+
problems.push(`${at}: '${IMPLICIT_ROW_KEY}' is implicit on every row and must not be declared as a field`);
|
|
266
|
+
}
|
|
267
|
+
if (seen.has(field.name))
|
|
268
|
+
problems.push(`${at}: field '${field.name}' is declared more than once`);
|
|
269
|
+
seen.add(field.name);
|
|
270
|
+
if (field.kind === 'relation' && !registeredNames.has(field.target)) {
|
|
271
|
+
problems.push(`${at}: field '${field.name}' targets '${field.target}', which is not a registered entity`);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
const titleField = descriptor.fields.find((field) => field.name === descriptor.titleField);
|
|
275
|
+
if (titleField === undefined) {
|
|
276
|
+
problems.push(`${at}: titleField '${descriptor.titleField}' does not name a declared field`);
|
|
277
|
+
}
|
|
278
|
+
else if (titleField.kind !== 'text') {
|
|
279
|
+
problems.push(`${at}: titleField '${descriptor.titleField}' is kind '${titleField.kind}'; a title must be 'text'`);
|
|
280
|
+
}
|
|
281
|
+
return problems;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Assembles entity ports into a registry, validating every descriptor first.
|
|
285
|
+
*
|
|
286
|
+
* Same ergonomics as `createAdminClient`: one object literal, `TPorts` inferred, host-owned and
|
|
287
|
+
* Jini-shipped entries indistinguishable. Registering an entity is one line.
|
|
288
|
+
*
|
|
289
|
+
* **No key is reserved.** `createAdminClient` reserves `'transport'` because it merges the
|
|
290
|
+
* transport into the same object it returns; this returns nothing but the ports, so there is
|
|
291
|
+
* nothing an entity named `transport` could shadow. The returned object has a `null` prototype, so
|
|
292
|
+
* a lookup by an attacker- or URL-supplied name (`'constructor'`, `'__proto__'`) resolves to
|
|
293
|
+
* `undefined` rather than walking to `Object.prototype` and yielding a truthy non-port.
|
|
294
|
+
*
|
|
295
|
+
* Deliberately takes no erasure options: a registry holds ports with their row types intact, and
|
|
296
|
+
* checking only becomes possible once those types are erased. `onViolation` therefore belongs to
|
|
297
|
+
* {@link getErasedEntityPort}/{@link listErasedEntityPorts}, at the point the guarantee is dropped.
|
|
298
|
+
*
|
|
299
|
+
* @param ports Entity name -> port. Each key must equal that port's `descriptor.name`.
|
|
300
|
+
* @returns A frozen, null-prototype registry preserving each port's own type.
|
|
301
|
+
* @throws {Error} listing *every* problem found, not just the first — a descriptor with three
|
|
302
|
+
* typos should take one round trip to fix, not three.
|
|
303
|
+
* @complexity Time O(entities × fields); space O(entities).
|
|
304
|
+
* @overallScore 100
|
|
305
|
+
*/
|
|
306
|
+
export function createAdminEntityRegistry(ports) {
|
|
307
|
+
const entries = Object.entries(ports);
|
|
308
|
+
const registeredNames = new Set(entries.map(([, port]) => port.descriptor.name));
|
|
309
|
+
const problems = entries.flatMap(([key, port]) => findDescriptorProblems(port.descriptor, key, registeredNames));
|
|
310
|
+
if (problems.length > 0) {
|
|
311
|
+
throw new Error(`createAdminEntityRegistry: invalid descriptors\n- ${problems.join('\n- ')}`);
|
|
312
|
+
}
|
|
313
|
+
const registry = Object.create(null);
|
|
314
|
+
for (const [key, port] of entries)
|
|
315
|
+
registry[key] = port;
|
|
316
|
+
return Object.freeze(registry);
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Every registered port, erased, in registration order — what a screen that renders any entity
|
|
320
|
+
* iterates.
|
|
321
|
+
*
|
|
322
|
+
* @complexity Time O(entities); space O(entities).
|
|
323
|
+
* @overallScore 100
|
|
324
|
+
*/
|
|
325
|
+
export function listErasedEntityPorts(registry, options = {}) {
|
|
326
|
+
return Object.values(registry).map((port) => eraseEntityPort(port, options));
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* The erased port registered under `name`, or `null`.
|
|
330
|
+
*
|
|
331
|
+
* `name` is routinely a URL segment, so this never trusts a bare property read: the registry's null
|
|
332
|
+
* prototype already stops `'constructor'` resolving to something truthy, and `Object.hasOwn` holds
|
|
333
|
+
* that guarantee even for a caller that hands in a plain object literal instead.
|
|
334
|
+
*
|
|
335
|
+
* @complexity Time O(1) for the lookup, O(1) for the erasure.
|
|
336
|
+
* @overallScore 100
|
|
337
|
+
*/
|
|
338
|
+
export function getErasedEntityPort(registry, name, options = {}) {
|
|
339
|
+
if (!Object.hasOwn(registry, name))
|
|
340
|
+
return null;
|
|
341
|
+
const port = registry[name];
|
|
342
|
+
return port === undefined ? null : eraseEntityPort(port, options);
|
|
343
|
+
}
|
|
344
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../../src/core/entities/rules.ts"],"names":[],"mappings":"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"}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -15,6 +15,10 @@ export { hasPermission } from './permissions/rules.js';
|
|
|
15
15
|
export { AdminApiError, createAdminClient, createHttpTransport, describeApiError, } from './transport/index.js';
|
|
16
16
|
export type { AdminClient, AdminRouteGroupFactory, AdminTransport, AdminFetch, HttpTransportOptions, } from './transport/index.js';
|
|
17
17
|
export type { GatedConfirmResult, GatedOperation, GatedPlanResult } from './gated/types.js';
|
|
18
|
+
export type { DataTableSortDirection, DataTableSortState } from './data-table/types.js';
|
|
18
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';
|
|
19
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';
|
|
20
24
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/core/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EACL,iBAAiB,EACjB,QAAQ,EACR,SAAS,EACT,kBAAkB,EAClB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG7F,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,kBAAkB,EAClB,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAGvD,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,WAAW,EACX,sBAAsB,EACtB,cAAc,EACd,UAAU,EACV,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAG9B,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"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"}
|
package/dist/core/index.js
CHANGED
|
@@ -12,4 +12,5 @@ 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';
|
|
15
16
|
//# sourceMappingURL=index.js.map
|
package/dist/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EACL,iBAAiB,EACjB,QAAQ,EACR,SAAS,EACT,kBAAkB,EAClB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EACL,kBAAkB,EAClB,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAE5B,kEAAkE;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,sDAAsD;AACtD,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EACL,iBAAiB,EACjB,QAAQ,EACR,SAAS,EACT,kBAAkB,EAClB,aAAa,GACd,MAAM,qBAAqB,CAAC;AAK7B,OAAO,EACL,kBAAkB,EAClB,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAE5B,kEAAkE;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,sDAAsD;AACtD,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,sBAAsB,CAAC;AA8I9B,OAAO,EACL,yBAAyB,EACzB,gCAAgC,EAChC,eAAe,EACf,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,qBAAqB,CAAC"}
|