@contember/bindx 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapter/ContemberAdapter.d.ts +40 -0
- package/dist/adapter/ContemberAdapter.d.ts.map +1 -0
- package/dist/adapter/MockAdapter.d.ts +81 -0
- package/dist/adapter/MockAdapter.d.ts.map +1 -0
- package/dist/adapter/MockQueryEngine.d.ts +43 -0
- package/dist/adapter/MockQueryEngine.d.ts.map +1 -0
- package/dist/adapter/index.d.ts +5 -0
- package/dist/adapter/index.d.ts.map +1 -0
- package/dist/adapter/types.d.ts +184 -0
- package/dist/adapter/types.d.ts.map +1 -0
- package/dist/brand/ComponentBrand.d.ts +25 -0
- package/dist/brand/ComponentBrand.d.ts.map +1 -0
- package/dist/contember/index.d.ts +10 -0
- package/dist/contember/index.d.ts.map +1 -0
- package/dist/core/ActionDispatcher.d.ts +64 -0
- package/dist/core/ActionDispatcher.d.ts.map +1 -0
- package/dist/core/Disposable.d.ts +57 -0
- package/dist/core/Disposable.d.ts.map +1 -0
- package/dist/core/EntityLoader.d.ts +80 -0
- package/dist/core/EntityLoader.d.ts.map +1 -0
- package/dist/core/PersistenceManager.d.ts +126 -0
- package/dist/core/PersistenceManager.d.ts.map +1 -0
- package/dist/core/SelectionResolver.d.ts +21 -0
- package/dist/core/SelectionResolver.d.ts.map +1 -0
- package/dist/core/actionClassification.d.ts +48 -0
- package/dist/core/actionClassification.d.ts.map +1 -0
- package/dist/core/actions.d.ts +301 -0
- package/dist/core/actions.d.ts.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/dataview/filterHandlers.d.ts +18 -0
- package/dist/dataview/filterHandlers.d.ts.map +1 -0
- package/dist/dataview/index.d.ts +3 -0
- package/dist/dataview/index.d.ts.map +1 -0
- package/dist/dataview/types.d.ts +164 -0
- package/dist/dataview/types.d.ts.map +1 -0
- package/dist/errors/UnfetchedFieldError.d.ts +11 -0
- package/dist/errors/UnfetchedFieldError.d.ts.map +1 -0
- package/dist/errors/errorPathResolver.d.ts +52 -0
- package/dist/errors/errorPathResolver.d.ts.map +1 -0
- package/dist/errors/index.d.ts +5 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/pathMapper.d.ts +42 -0
- package/dist/errors/pathMapper.d.ts.map +1 -0
- package/dist/errors/types.d.ts +131 -0
- package/dist/errors/types.d.ts.map +1 -0
- package/dist/events/EventEmitter.d.ts +97 -0
- package/dist/events/EventEmitter.d.ts.map +1 -0
- package/dist/events/eventFactory.d.ts +40 -0
- package/dist/events/eventFactory.d.ts.map +1 -0
- package/dist/events/index.d.ts +15 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/types.d.ts +264 -0
- package/dist/events/types.d.ts.map +1 -0
- package/dist/handles/BaseHandle.d.ts +64 -0
- package/dist/handles/BaseHandle.d.ts.map +1 -0
- package/dist/handles/EntityHandle.d.ts +208 -0
- package/dist/handles/EntityHandle.d.ts.map +1 -0
- package/dist/handles/FieldHandle.d.ts +111 -0
- package/dist/handles/FieldHandle.d.ts.map +1 -0
- package/dist/handles/HasManyListHandle.d.ts +166 -0
- package/dist/handles/HasManyListHandle.d.ts.map +1 -0
- package/dist/handles/HasOneHandle.d.ts +168 -0
- package/dist/handles/HasOneHandle.d.ts.map +1 -0
- package/dist/handles/PlaceholderHandle.d.ts +117 -0
- package/dist/handles/PlaceholderHandle.d.ts.map +1 -0
- package/dist/handles/index.d.ts +8 -0
- package/dist/handles/index.d.ts.map +1 -0
- package/dist/handles/proxyFactory.d.ts +66 -0
- package/dist/handles/proxyFactory.d.ts.map +1 -0
- package/dist/handles/types.d.ts +430 -0
- package/dist/handles/types.d.ts.map +1 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/internal.d.ts +11 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/persistence/BatchPersister.d.ts +142 -0
- package/dist/persistence/BatchPersister.d.ts.map +1 -0
- package/dist/persistence/ChangeRegistry.d.ts +87 -0
- package/dist/persistence/ChangeRegistry.d.ts.map +1 -0
- package/dist/persistence/ContemberSchemaMutationAdapter.d.ts +16 -0
- package/dist/persistence/ContemberSchemaMutationAdapter.d.ts.map +1 -0
- package/dist/persistence/MutationCollector.d.ts +96 -0
- package/dist/persistence/MutationCollector.d.ts.map +1 -0
- package/dist/persistence/MutationSchemaProvider.d.ts +30 -0
- package/dist/persistence/MutationSchemaProvider.d.ts.map +1 -0
- package/dist/persistence/index.d.ts +7 -0
- package/dist/persistence/index.d.ts.map +1 -0
- package/dist/persistence/types.d.ts +189 -0
- package/dist/persistence/types.d.ts.map +1 -0
- package/dist/roles/RoleSchemaRegistry.d.ts +77 -0
- package/dist/roles/RoleSchemaRegistry.d.ts.map +1 -0
- package/dist/roles/index.d.ts +11 -0
- package/dist/roles/index.d.ts.map +1 -0
- package/dist/roles/types.d.ts +242 -0
- package/dist/roles/types.d.ts.map +1 -0
- package/dist/schema/ContemberSchema.d.ts +98 -0
- package/dist/schema/ContemberSchema.d.ts.map +1 -0
- package/dist/schema/SchemaLoader.d.ts +28 -0
- package/dist/schema/SchemaLoader.d.ts.map +1 -0
- package/dist/schema/SchemaRegistry.d.ts +95 -0
- package/dist/schema/SchemaRegistry.d.ts.map +1 -0
- package/dist/schema/index.d.ts +6 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/roles.d.ts +62 -0
- package/dist/schema/roles.d.ts.map +1 -0
- package/dist/schema/types.d.ts +179 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/selection/SelectionMetaCollector.d.ts +32 -0
- package/dist/selection/SelectionMetaCollector.d.ts.map +1 -0
- package/dist/selection/SelectionScope.d.ts +77 -0
- package/dist/selection/SelectionScope.d.ts.map +1 -0
- package/dist/selection/buildQuery.d.ts +45 -0
- package/dist/selection/buildQuery.d.ts.map +1 -0
- package/dist/selection/createFragment.d.ts +29 -0
- package/dist/selection/createFragment.d.ts.map +1 -0
- package/dist/selection/createSelectionBuilder.d.ts +18 -0
- package/dist/selection/createSelectionBuilder.d.ts.map +1 -0
- package/dist/selection/index.d.ts +8 -0
- package/dist/selection/index.d.ts.map +1 -0
- package/dist/selection/queryTypes.d.ts +84 -0
- package/dist/selection/queryTypes.d.ts.map +1 -0
- package/dist/selection/types.d.ts +238 -0
- package/dist/selection/types.d.ts.map +1 -0
- package/dist/store/DirtyTracker.d.ts +26 -0
- package/dist/store/DirtyTracker.d.ts.map +1 -0
- package/dist/store/EntityMetaStore.d.ts +52 -0
- package/dist/store/EntityMetaStore.d.ts.map +1 -0
- package/dist/store/EntitySnapshotStore.d.ts +63 -0
- package/dist/store/EntitySnapshotStore.d.ts.map +1 -0
- package/dist/store/ErrorStore.d.ts +82 -0
- package/dist/store/ErrorStore.d.ts.map +1 -0
- package/dist/store/RelationStore.d.ts +175 -0
- package/dist/store/RelationStore.d.ts.map +1 -0
- package/dist/store/SnapshotStore.d.ts +143 -0
- package/dist/store/SnapshotStore.d.ts.map +1 -0
- package/dist/store/SubscriptionManager.d.ts +90 -0
- package/dist/store/SubscriptionManager.d.ts.map +1 -0
- package/dist/store/TouchedStore.d.ts +24 -0
- package/dist/store/TouchedStore.d.ts.map +1 -0
- package/dist/store/entityId.d.ts +29 -0
- package/dist/store/entityId.d.ts.map +1 -0
- package/dist/store/index.d.ts +1 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/snapshots.d.ts +144 -0
- package/dist/store/snapshots.d.ts.map +1 -0
- package/dist/undo/UndoManager.d.ts +120 -0
- package/dist/undo/UndoManager.d.ts.map +1 -0
- package/dist/undo/index.d.ts +3 -0
- package/dist/undo/index.d.ts.map +1 -0
- package/dist/undo/types.d.ts +74 -0
- package/dist/undo/types.d.ts.map +1 -0
- package/dist/utils/aliasGenerator.d.ts +25 -0
- package/dist/utils/aliasGenerator.d.ts.map +1 -0
- package/dist/utils/deepEqual.d.ts +6 -0
- package/dist/utils/deepEqual.d.ts.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/package.json +29 -0
- package/src/adapter/ContemberAdapter.ts +239 -0
- package/src/adapter/MockAdapter.ts +394 -0
- package/src/adapter/MockQueryEngine.ts +236 -0
- package/src/adapter/index.ts +21 -0
- package/src/adapter/types.ts +199 -0
- package/src/brand/ComponentBrand.ts +28 -0
- package/src/contember/index.ts +17 -0
- package/src/core/ActionDispatcher.ts +450 -0
- package/src/core/Disposable.ts +126 -0
- package/src/core/EntityLoader.ts +169 -0
- package/src/core/SelectionResolver.ts +78 -0
- package/src/core/actionClassification.ts +196 -0
- package/src/core/actions.ts +491 -0
- package/src/core/index.ts +20 -0
- package/src/dataview/filterHandlers.ts +443 -0
- package/src/dataview/index.ts +36 -0
- package/src/dataview/types.ts +220 -0
- package/src/errors/UnfetchedFieldError.ts +18 -0
- package/src/errors/errorPathResolver.ts +239 -0
- package/src/errors/index.ts +40 -0
- package/src/errors/pathMapper.ts +40 -0
- package/src/errors/types.ts +223 -0
- package/src/events/EventEmitter.ts +447 -0
- package/src/events/eventFactory.ts +430 -0
- package/src/events/index.ts +89 -0
- package/src/events/types.ts +374 -0
- package/src/handles/BaseHandle.ts +100 -0
- package/src/handles/EntityHandle.ts +538 -0
- package/src/handles/FieldHandle.ts +268 -0
- package/src/handles/HasManyListHandle.ts +500 -0
- package/src/handles/HasOneHandle.ts +500 -0
- package/src/handles/PlaceholderHandle.ts +321 -0
- package/src/handles/index.ts +37 -0
- package/src/handles/proxyFactory.ts +218 -0
- package/src/handles/types.ts +743 -0
- package/src/index.ts +384 -0
- package/src/internal.ts +19 -0
- package/src/persistence/BatchPersister.ts +911 -0
- package/src/persistence/ChangeRegistry.ts +150 -0
- package/src/persistence/ContemberSchemaMutationAdapter.ts +57 -0
- package/src/persistence/MutationCollector.ts +567 -0
- package/src/persistence/MutationSchemaProvider.ts +33 -0
- package/src/persistence/index.ts +23 -0
- package/src/persistence/types.ts +220 -0
- package/src/schema/ContemberSchema.ts +132 -0
- package/src/schema/SchemaLoader.ts +93 -0
- package/src/schema/SchemaRegistry.ts +286 -0
- package/src/schema/index.ts +51 -0
- package/src/schema/roles.ts +83 -0
- package/src/schema/types.ts +238 -0
- package/src/selection/SelectionMetaCollector.ts +122 -0
- package/src/selection/SelectionScope.ts +208 -0
- package/src/selection/buildQuery.ts +134 -0
- package/src/selection/createFragment.ts +50 -0
- package/src/selection/createSelectionBuilder.ts +283 -0
- package/src/selection/index.ts +31 -0
- package/src/selection/queryTypes.ts +135 -0
- package/src/selection/types.ts +320 -0
- package/src/store/DirtyTracker.ts +117 -0
- package/src/store/EntityMetaStore.ts +143 -0
- package/src/store/EntitySnapshotStore.ts +260 -0
- package/src/store/ErrorStore.ts +251 -0
- package/src/store/RelationStore.ts +696 -0
- package/src/store/SnapshotStore.ts +765 -0
- package/src/store/SubscriptionManager.ts +241 -0
- package/src/store/TouchedStore.ts +42 -0
- package/src/store/entityId.ts +43 -0
- package/src/store/index.ts +2 -0
- package/src/store/snapshots.ts +203 -0
- package/src/undo/UndoManager.ts +418 -0
- package/src/undo/index.ts +9 -0
- package/src/undo/types.ts +84 -0
- package/src/utils/aliasGenerator.ts +56 -0
- package/src/utils/deepEqual.ts +33 -0
- package/src/utils/index.ts +2 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime registry for role-based schemas.
|
|
3
|
+
*
|
|
4
|
+
* Manages multiple schema registries (one per role) and provides
|
|
5
|
+
* utilities for role-aware field access and query building.
|
|
6
|
+
*/
|
|
7
|
+
import { SchemaRegistry } from '../schema/SchemaRegistry.js';
|
|
8
|
+
import type { RoleSchemaDefinitions } from './types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Registry that manages multiple schemas, one for each role.
|
|
11
|
+
*
|
|
12
|
+
* @typeParam TRoleSchemas - Map of role names to their model types
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* interface RoleSchemas {
|
|
17
|
+
* public: { Article: PublicArticle; Author: PublicAuthor }
|
|
18
|
+
* editor: { Article: EditorArticle; Author: EditorAuthor }
|
|
19
|
+
* admin: { Article: AdminArticle; Author: AdminAuthor }
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* const registry = new RoleSchemaRegistry<RoleSchemas>({
|
|
23
|
+
* public: publicSchemaDefinition,
|
|
24
|
+
* editor: editorSchemaDefinition,
|
|
25
|
+
* admin: adminSchemaDefinition,
|
|
26
|
+
* })
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare class RoleSchemaRegistry<TRoleSchemas extends {
|
|
30
|
+
[K in keyof TRoleSchemas]: {
|
|
31
|
+
[E: string]: object;
|
|
32
|
+
};
|
|
33
|
+
}> {
|
|
34
|
+
private readonly registries;
|
|
35
|
+
private readonly roleNames;
|
|
36
|
+
constructor(schemas: RoleSchemaDefinitions<TRoleSchemas>);
|
|
37
|
+
/**
|
|
38
|
+
* Gets all registered role names.
|
|
39
|
+
*/
|
|
40
|
+
getRoleNames(): readonly (keyof TRoleSchemas)[];
|
|
41
|
+
/**
|
|
42
|
+
* Gets the SchemaRegistry for a specific role.
|
|
43
|
+
*/
|
|
44
|
+
getSchemaForRole<TRole extends keyof TRoleSchemas>(role: TRole): SchemaRegistry;
|
|
45
|
+
/**
|
|
46
|
+
* Checks if a role exists in the registry.
|
|
47
|
+
*/
|
|
48
|
+
hasRole(role: keyof TRoleSchemas): boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Gets field names available for an entity across ALL specified roles (intersection).
|
|
51
|
+
*
|
|
52
|
+
* @param roles - Roles to check
|
|
53
|
+
* @param entityName - Entity to get fields for
|
|
54
|
+
* @returns Array of field names available in ALL specified roles
|
|
55
|
+
*/
|
|
56
|
+
getFieldsForRoles(roles: readonly (keyof TRoleSchemas)[], entityName: string): string[];
|
|
57
|
+
/**
|
|
58
|
+
* Gets entity names available across ALL specified roles (intersection).
|
|
59
|
+
*
|
|
60
|
+
* @param roles - Roles to check
|
|
61
|
+
* @returns Array of entity names available in ALL specified roles
|
|
62
|
+
*/
|
|
63
|
+
getEntityNamesForRoles(roles: readonly (keyof TRoleSchemas)[]): string[];
|
|
64
|
+
/**
|
|
65
|
+
* Checks if a field is accessible for all specified roles.
|
|
66
|
+
*/
|
|
67
|
+
isFieldAccessible(roles: readonly (keyof TRoleSchemas)[], entityName: string, fieldName: string): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Checks if an entity is accessible for all specified roles.
|
|
70
|
+
*/
|
|
71
|
+
isEntityAccessible(roles: readonly (keyof TRoleSchemas)[], entityName: string): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Validates all registered schemas.
|
|
74
|
+
*/
|
|
75
|
+
validate(): void;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=RoleSchemaRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RoleSchemaRegistry.d.ts","sourceRoot":"","sources":["../../src/roles/RoleSchemaRegistry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAE5D,OAAO,KAAK,EAAE,qBAAqB,EAAa,MAAM,YAAY,CAAA;AAElE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,kBAAkB,CAAC,YAAY,SAAS;KAAG,CAAC,IAAI,MAAM,YAAY,GAAG;QAAE,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE;CAAE;IAC1G,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyC;IACpE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiC;gBAE/C,OAAO,EAAE,qBAAqB,CAAC,YAAY,CAAC;IAUxD;;OAEG;IACH,YAAY,IAAI,SAAS,CAAC,MAAM,YAAY,CAAC,EAAE;IAI/C;;OAEG;IACH,gBAAgB,CAAC,KAAK,SAAS,MAAM,YAAY,EAAE,IAAI,EAAE,KAAK,GAAG,cAAc;IAQ/E;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,YAAY,GAAG,OAAO;IAI1C;;;;;;OAMG;IACH,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,YAAY,CAAC,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IA6BvF;;;;;OAKG;IACH,sBAAsB,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,YAAY,CAAC,EAAE,GAAG,MAAM,EAAE;IA6BxE;;OAEG;IACH,iBAAiB,CAChB,KAAK,EAAE,SAAS,CAAC,MAAM,YAAY,CAAC,EAAE,EACtC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GACf,OAAO;IAgBV;;OAEG;IACH,kBAAkB,CACjB,KAAK,EAAE,SAAS,CAAC,MAAM,YAAY,CAAC,EAAE,EACtC,UAAU,EAAE,MAAM,GAChB,OAAO;IAWV;;OAEG;IACH,QAAQ,IAAI,IAAI;CAWhB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role-based schema module for Bindx.
|
|
3
|
+
*
|
|
4
|
+
* Provides type-safe role-aware entity access with schema narrowing.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
export type { UnionToIntersection, RoleSchemaMap, RoleNames, IntersectRoleSchemas, IntersectSchemaEntities, PickCommonProperties, EntityForRoles, SchemaForRole, EntityNamesForRoles, RoleSchemaDefinitions, RoleBindxConfig, RolesAreSubset, RequireRoleSubset, AssertRoleCompatibility, SingleSchemaRoles, IsSingleSchema, AllRoles, DefaultRole, } from './types.js';
|
|
9
|
+
export { isValidRole, DEFAULT_ROLE } from './types.js';
|
|
10
|
+
export { RoleSchemaRegistry } from './RoleSchemaRegistry.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/roles/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EACX,mBAAmB,EACnB,aAAa,EACb,SAAS,EACT,oBAAoB,EACpB,uBAAuB,EACvB,oBAAoB,EACpB,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,qBAAqB,EACrB,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,iBAAiB,EACjB,cAAc,EACd,QAAQ,EACR,WAAW,GACX,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role-based schema types for Bindx.
|
|
3
|
+
*
|
|
4
|
+
* Provides type-safe role-aware entity access with schema narrowing
|
|
5
|
+
* based on user roles.
|
|
6
|
+
*/
|
|
7
|
+
import type { SchemaDefinition, EntitySchemaDef } from '../schema/types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Converts a union type to an intersection type.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* type Union = { a: string } | { b: number }
|
|
14
|
+
* type Intersection = UnionToIntersection<Union>
|
|
15
|
+
* // Result: { a: string } & { b: number }
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export type UnionToIntersection<U> = (U extends unknown ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
19
|
+
/**
|
|
20
|
+
* Extracts keys that exist in ALL members of a union type.
|
|
21
|
+
* Uses distributive conditional to check each union member.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* type A = { id: string; title: string; content: string }
|
|
26
|
+
* type B = { id: string; title: string; notes: string }
|
|
27
|
+
* type Common = KeysInAll<A | B>
|
|
28
|
+
* // Result: 'id' | 'title'
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
type KeysInAll<T, K = keyof T> = T extends unknown ? K extends keyof T ? K : never : never;
|
|
32
|
+
/**
|
|
33
|
+
* Picks only the common properties from a union of object types.
|
|
34
|
+
* Returns an object with only keys that exist in ALL union members.
|
|
35
|
+
* Property values are unions of the original types.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* type A = { id: string; title: string; content: string }
|
|
40
|
+
* type B = { id: string; title: string; notes: string }
|
|
41
|
+
* type Common = PickCommonProperties<A | B>
|
|
42
|
+
* // Result: { id: string; title: string }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export type PickCommonProperties<T> = {
|
|
46
|
+
[K in KeysInAll<T>]: T extends {
|
|
47
|
+
readonly [P in K]: infer V;
|
|
48
|
+
} ? V : never;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Applies PickCommonProperties to each entity in a schema union.
|
|
52
|
+
* For a union of schemas, extracts only common entity names and their common properties.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* type SchemaA = { Article: { id: string; title: string }; Author: { id: string } }
|
|
57
|
+
* type SchemaB = { Article: { id: string; content: string }; Author: { id: string } }
|
|
58
|
+
* type Common = IntersectSchemaEntities<SchemaA | SchemaB>
|
|
59
|
+
* // Result: { Article: { id: string }; Author: { id: string } }
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export type IntersectSchemaEntities<TSchemaUnion> = {
|
|
63
|
+
[K in KeysInAll<TSchemaUnion>]: PickCommonProperties<TSchemaUnion extends {
|
|
64
|
+
readonly [P in K]: infer V;
|
|
65
|
+
} ? V : never>;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Base constraint for role schema maps.
|
|
69
|
+
* Uses a mapped type to allow interfaces without index signatures.
|
|
70
|
+
*/
|
|
71
|
+
export type RoleSchemasConstraint = {
|
|
72
|
+
[role: string]: {
|
|
73
|
+
[entity: string]: object;
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Mapping of role names to their respective schema types.
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* interface MyRoleSchemas {
|
|
82
|
+
* public: PublicSchema
|
|
83
|
+
* editor: EditorSchema
|
|
84
|
+
* admin: AdminSchema
|
|
85
|
+
* }
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export type RoleSchemaMap<TRoleSchemas> = {
|
|
89
|
+
[K in keyof TRoleSchemas]: TRoleSchemas[K];
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Extracts all role names from a role schema map.
|
|
93
|
+
*/
|
|
94
|
+
export type RoleNames<TRoleSchemas> = keyof TRoleSchemas & string;
|
|
95
|
+
/**
|
|
96
|
+
* Intersects schemas from multiple roles.
|
|
97
|
+
* Used when multiple roles are specified - returns fields accessible to ALL roles.
|
|
98
|
+
*
|
|
99
|
+
* This performs a TRUE property intersection: only properties that exist in ALL
|
|
100
|
+
* role schemas are accessible. This is different from TypeScript's & operator
|
|
101
|
+
* which creates a type with ALL properties from all schemas.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```typescript
|
|
105
|
+
* interface EditorSchema { Article: { id: string; title: string; content: string } }
|
|
106
|
+
* interface ReviewerSchema { Article: { id: string; title: string; status: string } }
|
|
107
|
+
*
|
|
108
|
+
* type Combined = IntersectRoleSchemas<{ editor: EditorSchema; reviewer: ReviewerSchema }, ['editor', 'reviewer']>
|
|
109
|
+
* // Result: { Article: { id: string; title: string } } (only common properties)
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
export type IntersectRoleSchemas<TRoleSchemas, TRoles extends readonly (keyof TRoleSchemas)[]> = IntersectSchemaEntities<TRoleSchemas[TRoles[number]]>;
|
|
113
|
+
/**
|
|
114
|
+
* Gets the entity type for specific roles.
|
|
115
|
+
*
|
|
116
|
+
* @typeParam TRoleSchemas - Map of role names to their schemas
|
|
117
|
+
* @typeParam TRoles - Tuple of role names to intersect
|
|
118
|
+
* @typeParam TEntityName - Name of the entity to extract
|
|
119
|
+
*/
|
|
120
|
+
export type EntityForRoles<TRoleSchemas, TRoles extends readonly (keyof TRoleSchemas)[], TEntityName extends string> = TEntityName extends keyof IntersectRoleSchemas<TRoleSchemas, TRoles> ? IntersectRoleSchemas<TRoleSchemas, TRoles>[TEntityName] : never;
|
|
121
|
+
/**
|
|
122
|
+
* Gets the schema type for a specific role.
|
|
123
|
+
*/
|
|
124
|
+
export type SchemaForRole<TRoleSchemas, TRole extends keyof TRoleSchemas> = TRoleSchemas[TRole];
|
|
125
|
+
/**
|
|
126
|
+
* Extracts all entity names that exist in ALL specified roles.
|
|
127
|
+
*/
|
|
128
|
+
export type EntityNamesForRoles<TRoleSchemas, TRoles extends readonly (keyof TRoleSchemas)[]> = keyof IntersectRoleSchemas<TRoleSchemas, TRoles> & string;
|
|
129
|
+
/**
|
|
130
|
+
* Maps role names to their schema definitions (runtime structure).
|
|
131
|
+
*/
|
|
132
|
+
export type RoleSchemaDefinitions<TRoleSchemas> = {
|
|
133
|
+
[K in keyof TRoleSchemas]: TRoleSchemas[K] extends {
|
|
134
|
+
[E: string]: object;
|
|
135
|
+
} ? SchemaDefinition<TRoleSchemas[K]> : never;
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Configuration for role-aware bindx.
|
|
139
|
+
*/
|
|
140
|
+
export interface RoleBindxConfig<TRoleSchemas> {
|
|
141
|
+
/**
|
|
142
|
+
* Schema definitions for each role.
|
|
143
|
+
*/
|
|
144
|
+
readonly schemas: RoleSchemaDefinitions<TRoleSchemas>;
|
|
145
|
+
/**
|
|
146
|
+
* Function to check if the current user has a specific role.
|
|
147
|
+
* Used at runtime to determine which branches to render.
|
|
148
|
+
*/
|
|
149
|
+
readonly hasRole: (role: keyof TRoleSchemas) => boolean;
|
|
150
|
+
/**
|
|
151
|
+
* Current roles of the user.
|
|
152
|
+
* Used for query building - determines which fields to fetch.
|
|
153
|
+
*/
|
|
154
|
+
readonly currentRoles: readonly (keyof TRoleSchemas)[];
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Check if TRequired roles are a subset of TAvailable roles.
|
|
158
|
+
* Returns true if every role in TRequired exists in TAvailable.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```typescript
|
|
162
|
+
* type Test1 = RolesAreSubset<['admin'], ['editor', 'admin']> // true
|
|
163
|
+
* type Test2 = RolesAreSubset<['admin'], ['editor']> // false
|
|
164
|
+
* type Test3 = RolesAreSubset<[], ['editor']> // true (empty is subset of all)
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
export type RolesAreSubset<TRequired extends readonly string[], TAvailable extends readonly string[]> = TRequired extends readonly [] ? true : TRequired extends readonly [infer First extends string, ...infer Rest extends string[]] ? First extends TAvailable[number] ? RolesAreSubset<Rest, TAvailable> : false : boolean;
|
|
168
|
+
/**
|
|
169
|
+
* Enforces that TRequired roles must be a subset of TAvailable roles.
|
|
170
|
+
* Returns TRequired if valid, never if not.
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* ```typescript
|
|
174
|
+
* type Valid = RequireRoleSubset<['admin'], ['editor', 'admin']> // ['admin']
|
|
175
|
+
* type Invalid = RequireRoleSubset<['admin'], ['editor']> // never
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
export type RequireRoleSubset<TRequired extends readonly string[], TAvailable extends readonly string[]> = RolesAreSubset<TRequired, TAvailable> extends true ? TRequired : never;
|
|
179
|
+
/**
|
|
180
|
+
* Asserts that TComponentRoles are compatible with TAvailableRoles.
|
|
181
|
+
* Used for type-level validation when using role-aware components.
|
|
182
|
+
*
|
|
183
|
+
* When component requires ['admin'] and scope has ['editor', 'admin']:
|
|
184
|
+
* - ['admin'] ⊆ ['editor', 'admin'] = true (compatible)
|
|
185
|
+
*
|
|
186
|
+
* When component requires ['admin'] and scope has ['editor']:
|
|
187
|
+
* - ['admin'] ⊆ ['editor'] = false (incompatible)
|
|
188
|
+
*/
|
|
189
|
+
export type AssertRoleCompatibility<TComponentRoles extends readonly string[], TAvailableRoles extends readonly string[]> = RolesAreSubset<TComponentRoles, TAvailableRoles> extends true ? TComponentRoles : ['Error: Component requires roles', TComponentRoles, 'but available roles are', TAvailableRoles];
|
|
190
|
+
/**
|
|
191
|
+
* Type predicate to check if a value is a valid role.
|
|
192
|
+
*/
|
|
193
|
+
export declare function isValidRole<TRoleSchemas>(roleSchemas: TRoleSchemas, role: unknown): role is keyof TRoleSchemas;
|
|
194
|
+
export type { SchemaDefinition, EntitySchemaDef };
|
|
195
|
+
/**
|
|
196
|
+
* Wraps a single schema as a role schema map with a default role.
|
|
197
|
+
* This allows single-schema usage to be a special case of role-aware bindx.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```typescript
|
|
201
|
+
* type Models = { Article: ArticleType; Author: AuthorType }
|
|
202
|
+
*
|
|
203
|
+
* // Single schema becomes:
|
|
204
|
+
* type RoleSchemas = SingleSchemaRoles<Models>
|
|
205
|
+
* // = { _default: { Article: ArticleType; Author: AuthorType } }
|
|
206
|
+
*
|
|
207
|
+
* // IntersectRoleSchemas<RoleSchemas, ['_default']> = Models
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
export type SingleSchemaRoles<TModels extends Record<string, object>> = {
|
|
211
|
+
_default: TModels;
|
|
212
|
+
};
|
|
213
|
+
/**
|
|
214
|
+
* Check if TRoleSchemas represents a single-schema case.
|
|
215
|
+
* Returns true if the only key is '_default'.
|
|
216
|
+
*
|
|
217
|
+
* @example
|
|
218
|
+
* ```typescript
|
|
219
|
+
* type Test1 = IsSingleSchema<{ _default: Models }> // true
|
|
220
|
+
* type Test2 = IsSingleSchema<{ admin: AdminModels; public: PublicModels }> // false
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
export type IsSingleSchema<TRoleSchemas> = keyof TRoleSchemas extends '_default' ? '_default' extends keyof TRoleSchemas ? true : false : false;
|
|
224
|
+
/**
|
|
225
|
+
* Gets all role names from a role schema map as a readonly array type.
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
* ```typescript
|
|
229
|
+
* type Roles = AllRoles<{ admin: AdminModels; public: PublicModels }>
|
|
230
|
+
* // = readonly ('admin' | 'public')[]
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
export type AllRoles<TRoleSchemas> = readonly (keyof TRoleSchemas & string)[];
|
|
234
|
+
/**
|
|
235
|
+
* Default role name for single-schema case.
|
|
236
|
+
*/
|
|
237
|
+
export declare const DEFAULT_ROLE: "_default";
|
|
238
|
+
/**
|
|
239
|
+
* Type for the default role name.
|
|
240
|
+
*/
|
|
241
|
+
export type DefaultRole = typeof DEFAULT_ROLE;
|
|
242
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/roles/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAM3E;;;;;;;;;GASG;AACH,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAChC,CAAC,CAAC,SAAS,OAAO,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,IAAI,GACtE,CAAC,GACD,KAAK,CAAA;AAET;;;;;;;;;;;GAWG;AACH,KAAK,SAAS,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,OAAO,GAC/C,CAAC,SAAS,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,GAC7B,KAAK,CAAA;AAER;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI;KACpC,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS;QAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;KAAE,GAAG,CAAC,GAAG,KAAK;CACzE,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,uBAAuB,CAAC,YAAY,IAAI;KAClD,CAAC,IAAI,SAAS,CAAC,YAAY,CAAC,GAAG,oBAAoB,CACnD,YAAY,SAAS;QAAE,QAAQ,EAAE,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;KAAE,GAAG,CAAC,GAAG,KAAK,CAC/D;CACD,CAAA;AAMD;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IACnC,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;CAC5C,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,aAAa,CAAC,YAAY,IAAI;KACxC,CAAC,IAAI,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC;CAC1C,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,CAAC,YAAY,IAAI,MAAM,YAAY,GAAG,MAAM,CAAA;AAEjE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,oBAAoB,CAC/B,YAAY,EACZ,MAAM,SAAS,SAAS,CAAC,MAAM,YAAY,CAAC,EAAE,IAC3C,uBAAuB,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;AAEzD;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,CACzB,YAAY,EACZ,MAAM,SAAS,SAAS,CAAC,MAAM,YAAY,CAAC,EAAE,EAC9C,WAAW,SAAS,MAAM,IACvB,WAAW,SAAS,MAAM,oBAAoB,CAAC,YAAY,EAAE,MAAM,CAAC,GACrE,oBAAoB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,WAAW,CAAC,GACvD,KAAK,CAAA;AAER;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,YAAY,EAAE,KAAK,SAAS,MAAM,YAAY,IACvE,YAAY,CAAC,KAAK,CAAC,CAAA;AAEpB;;GAEG;AACH,MAAM,MAAM,mBAAmB,CAC9B,YAAY,EACZ,MAAM,SAAS,SAAS,CAAC,MAAM,YAAY,CAAC,EAAE,IAC3C,MAAM,oBAAoB,CAAC,YAAY,EAAE,MAAM,CAAC,GAAG,MAAM,CAAA;AAM7D;;GAEG;AACH,MAAM,MAAM,qBAAqB,CAAC,YAAY,IAAI;KAChD,CAAC,IAAI,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,SAAS;QAAE,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GACvE,gBAAgB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,GACjC,KAAK;CACR,CAAA;AAED;;GAEG;AACH,MAAM,WAAW,eAAe,CAAC,YAAY;IAC5C;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC,YAAY,CAAC,CAAA;IAErD;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,YAAY,KAAK,OAAO,CAAA;IAEvD;;;OAGG;IACH,QAAQ,CAAC,YAAY,EAAE,SAAS,CAAC,MAAM,YAAY,CAAC,EAAE,CAAA;CACtD;AAMD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,cAAc,CACzB,SAAS,SAAS,SAAS,MAAM,EAAE,EACnC,UAAU,SAAS,SAAS,MAAM,EAAE,IACjC,SAAS,SAAS,SAAS,EAAE,GAC9B,IAAI,GACJ,SAAS,SAAS,SAAS,CAAC,MAAM,KAAK,SAAS,MAAM,EAAE,GAAG,MAAM,IAAI,SAAS,MAAM,EAAE,CAAC,GACtF,KAAK,SAAS,UAAU,CAAC,MAAM,CAAC,GAC/B,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,GAChC,KAAK,GACN,OAAO,CAAA;AAEX;;;;;;;;;GASG;AACH,MAAM,MAAM,iBAAiB,CAC5B,SAAS,SAAS,SAAS,MAAM,EAAE,EACnC,UAAU,SAAS,SAAS,MAAM,EAAE,IACjC,cAAc,CAAC,SAAS,EAAE,UAAU,CAAC,SAAS,IAAI,GAAG,SAAS,GAAG,KAAK,CAAA;AAE1E;;;;;;;;;GASG;AACH,MAAM,MAAM,uBAAuB,CAClC,eAAe,SAAS,SAAS,MAAM,EAAE,EACzC,eAAe,SAAS,SAAS,MAAM,EAAE,IACtC,cAAc,CAAC,eAAe,EAAE,eAAe,CAAC,SAAS,IAAI,GAC9D,eAAe,GACf,CAAC,iCAAiC,EAAE,eAAe,EAAE,yBAAyB,EAAE,eAAe,CAAC,CAAA;AAMnG;;GAEG;AACH,wBAAgB,WAAW,CAAC,YAAY,EACvC,WAAW,EAAE,YAAY,EACzB,IAAI,EAAE,OAAO,GACX,IAAI,IAAI,MAAM,YAAY,CAE5B;AAMD,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAA;AAMjD;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,iBAAiB,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI;IACvE,QAAQ,EAAE,OAAO,CAAA;CACjB,CAAA;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,cAAc,CAAC,YAAY,IACtC,MAAM,YAAY,SAAS,UAAU,GAClC,UAAU,SAAS,MAAM,YAAY,GACpC,IAAI,GACJ,KAAK,GACN,KAAK,CAAA;AAET;;;;;;;;GAQG;AACH,MAAM,MAAM,QAAQ,CAAC,YAAY,IAAI,SAAS,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,EAAE,CAAA;AAE7E;;GAEG;AACH,eAAO,MAAM,YAAY,EAAG,UAAmB,CAAA;AAE/C;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,YAAY,CAAA"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types matching the Contember API schema introspection format.
|
|
3
|
+
* These types are compatible with binding-common's Schema.
|
|
4
|
+
*/
|
|
5
|
+
export type SchemaColumnType = 'Bool' | 'Date' | 'DateTime' | 'Double' | 'Enum' | 'Integer' | 'String' | 'Uuid' | 'Json' | string;
|
|
6
|
+
export interface SchemaColumn {
|
|
7
|
+
__typename: '_Column';
|
|
8
|
+
name: string;
|
|
9
|
+
nullable: boolean;
|
|
10
|
+
type: SchemaColumnType;
|
|
11
|
+
enumName: string | null;
|
|
12
|
+
defaultValue: string | number | boolean | null;
|
|
13
|
+
}
|
|
14
|
+
export interface SchemaRelationOrderBy {
|
|
15
|
+
path: string[];
|
|
16
|
+
direction: 'asc' | 'desc';
|
|
17
|
+
}
|
|
18
|
+
interface BaseRelation {
|
|
19
|
+
__typename: '_Relation';
|
|
20
|
+
name: string;
|
|
21
|
+
nullable: boolean | null;
|
|
22
|
+
onDelete: 'restrict' | 'cascade' | 'setNull' | null;
|
|
23
|
+
orderBy: SchemaRelationOrderBy[] | null;
|
|
24
|
+
orphanRemoval: boolean | null;
|
|
25
|
+
targetEntity: string;
|
|
26
|
+
type: 'OneHasOne' | 'OneHasMany' | 'ManyHasOne' | 'ManyHasMany';
|
|
27
|
+
}
|
|
28
|
+
export interface OwningRelation extends BaseRelation {
|
|
29
|
+
side: 'owning';
|
|
30
|
+
inversedBy: string | null;
|
|
31
|
+
ownedBy?: never;
|
|
32
|
+
}
|
|
33
|
+
export interface InverseRelation extends BaseRelation {
|
|
34
|
+
side: 'inverse';
|
|
35
|
+
ownedBy: string;
|
|
36
|
+
inversedBy?: never;
|
|
37
|
+
}
|
|
38
|
+
export type SchemaRelation = OwningRelation | InverseRelation;
|
|
39
|
+
export type SchemaField = SchemaColumn | SchemaRelation;
|
|
40
|
+
export interface SchemaEntity {
|
|
41
|
+
name: string;
|
|
42
|
+
customPrimaryAllowed: boolean;
|
|
43
|
+
fields: Map<string, SchemaField>;
|
|
44
|
+
unique: {
|
|
45
|
+
fields: Set<string>;
|
|
46
|
+
}[];
|
|
47
|
+
}
|
|
48
|
+
export interface SchemaEnum {
|
|
49
|
+
name: string;
|
|
50
|
+
values: string[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Processed schema store with Maps for efficient lookup.
|
|
54
|
+
* This is the format used internally after loading from API.
|
|
55
|
+
*/
|
|
56
|
+
export interface ContemberSchemaStore {
|
|
57
|
+
entities: Map<string, SchemaEntity>;
|
|
58
|
+
enums: Map<string, Set<string>>;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Raw schema format as returned by the Contember API.
|
|
62
|
+
*/
|
|
63
|
+
export interface RawContemberSchema {
|
|
64
|
+
enums: {
|
|
65
|
+
name: string;
|
|
66
|
+
values: string[];
|
|
67
|
+
}[];
|
|
68
|
+
entities: {
|
|
69
|
+
name: string;
|
|
70
|
+
customPrimaryAllowed: boolean;
|
|
71
|
+
fields: (SchemaColumn | (Omit<SchemaRelation, 'side'> & {
|
|
72
|
+
side: 'owning' | 'inverse';
|
|
73
|
+
ownedBy?: string;
|
|
74
|
+
inversedBy?: string | null;
|
|
75
|
+
}))[];
|
|
76
|
+
unique: {
|
|
77
|
+
fields: string[];
|
|
78
|
+
}[];
|
|
79
|
+
}[];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Schema class compatible with binding-common's Schema.
|
|
83
|
+
* Can be used directly or created from API response.
|
|
84
|
+
*/
|
|
85
|
+
export declare class ContemberSchema {
|
|
86
|
+
private readonly store;
|
|
87
|
+
constructor(store: ContemberSchemaStore);
|
|
88
|
+
getEntity(entityName: string): SchemaEntity | undefined;
|
|
89
|
+
getEntityNames(): string[];
|
|
90
|
+
getEntityField(entityName: string, fieldName: string): SchemaField | undefined;
|
|
91
|
+
getEnumValues(enumName: string): string[] | undefined;
|
|
92
|
+
/**
|
|
93
|
+
* Creates a ContemberSchema from raw API response.
|
|
94
|
+
*/
|
|
95
|
+
static fromRaw(raw: RawContemberSchema): ContemberSchema;
|
|
96
|
+
}
|
|
97
|
+
export {};
|
|
98
|
+
//# sourceMappingURL=ContemberSchema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContemberSchema.d.ts","sourceRoot":"","sources":["../../src/schema/ContemberSchema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loads schema from Contember Content API via GraphQL introspection.
|
|
3
|
+
*/
|
|
4
|
+
import { ContemberSchema } from './ContemberSchema.js';
|
|
5
|
+
export interface SchemaLoaderClient {
|
|
6
|
+
execute<T>(query: string, options?: unknown): Promise<T>;
|
|
7
|
+
apiUrl?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Loads and caches schema from Contember Content API.
|
|
11
|
+
* Instance-level cache avoids cross-tenant collisions and test pollution.
|
|
12
|
+
*/
|
|
13
|
+
export declare class SchemaLoader {
|
|
14
|
+
private readonly cache;
|
|
15
|
+
/**
|
|
16
|
+
* Loads schema from the API, with caching per API URL.
|
|
17
|
+
*/
|
|
18
|
+
loadSchema(client: SchemaLoaderClient, options?: unknown): Promise<ContemberSchema>;
|
|
19
|
+
/**
|
|
20
|
+
* Clears the schema cache.
|
|
21
|
+
*/
|
|
22
|
+
clearCache(): void;
|
|
23
|
+
/**
|
|
24
|
+
* Clears cache for a specific API URL.
|
|
25
|
+
*/
|
|
26
|
+
clearCacheFor(apiUrl: string): void;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=SchemaLoader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaLoader.d.ts","sourceRoot":"","sources":["../../src/schema/SchemaLoader.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAA2B,MAAM,sBAAsB,CAAA;AAE/E,MAAM,WAAW,kBAAkB;IAClC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACxD,MAAM,CAAC,EAAE,MAAM,CAAA;CACf;AAwCD;;;GAGG;AACH,qBAAa,YAAY;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8C;IAEpE;;OAEG;IACG,UAAU,CACf,MAAM,EAAE,kBAAkB,EAC1B,OAAO,CAAC,EAAE,OAAO,GACf,OAAO,CAAC,eAAe,CAAC;IAiB3B;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;CAGnC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { ContemberSchema } from './ContemberSchema.js';
|
|
2
|
+
import type { EntitySchemaDef, FieldDef, RelationType, SchemaDefinition } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Runtime registry for entity schemas.
|
|
5
|
+
* Provides lookups for entity definitions, relation targets, and field types.
|
|
6
|
+
*/
|
|
7
|
+
export declare class SchemaRegistry<TModels extends Record<string, object> = Record<string, object>> {
|
|
8
|
+
private readonly entityDefs;
|
|
9
|
+
constructor(definition: SchemaDefinition<TModels>);
|
|
10
|
+
/**
|
|
11
|
+
* Creates a SchemaRegistry from a ContemberSchema (loaded from API or injected).
|
|
12
|
+
* This is the preferred way to create a SchemaRegistry at runtime.
|
|
13
|
+
*/
|
|
14
|
+
static fromContemberSchema(schema: ContemberSchema): SchemaRegistry;
|
|
15
|
+
/**
|
|
16
|
+
* Gets the entity names defined in the schema
|
|
17
|
+
*/
|
|
18
|
+
getEntityNames(): string[];
|
|
19
|
+
/**
|
|
20
|
+
* Checks if an entity type exists in the schema
|
|
21
|
+
*/
|
|
22
|
+
hasEntity(entityType: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Gets the schema definition for an entity type
|
|
25
|
+
*/
|
|
26
|
+
getEntityDef(entityType: string): EntitySchemaDef | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Gets the field definition for a specific field on an entity
|
|
29
|
+
*/
|
|
30
|
+
getFieldDef(entityType: string, fieldName: string): FieldDef | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Gets the enum values for an enum field.
|
|
33
|
+
* Returns undefined if the field is not an enum or doesn't exist.
|
|
34
|
+
*/
|
|
35
|
+
getEnumValues(entityType: string, fieldName: string): readonly string[] | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Gets the enum name for an enum field.
|
|
38
|
+
* Returns undefined if the field is not an enum or doesn't exist.
|
|
39
|
+
*/
|
|
40
|
+
getEnumName(entityType: string, fieldName: string): string | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Gets the column type for a scalar field (e.g. 'String', 'Integer', 'Date').
|
|
43
|
+
* Returns undefined if the field is not a scalar or doesn't exist.
|
|
44
|
+
*/
|
|
45
|
+
getColumnType(entityType: string, fieldName: string): string | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Gets the target entity type for a relation field.
|
|
48
|
+
* Returns undefined if the field is not a relation or doesn't exist.
|
|
49
|
+
*/
|
|
50
|
+
getRelationTarget(entityType: string, fieldName: string): string | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* Gets the relation type for a field (hasOne or hasMany).
|
|
53
|
+
* Returns undefined if the field is not a relation.
|
|
54
|
+
*/
|
|
55
|
+
getRelationType(entityType: string, fieldName: string): RelationType | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* Checks if a field is a relation (hasOne or hasMany)
|
|
58
|
+
*/
|
|
59
|
+
isRelation(entityType: string, fieldName: string): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Checks if a field is a has-one relation
|
|
62
|
+
*/
|
|
63
|
+
isHasOne(entityType: string, fieldName: string): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Checks if a field is a has-many relation
|
|
66
|
+
*/
|
|
67
|
+
isHasMany(entityType: string, fieldName: string): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Checks if a field is a scalar (non-relation) field
|
|
70
|
+
*/
|
|
71
|
+
isScalar(entityType: string, fieldName: string): boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Gets the inverse field name for a relation.
|
|
74
|
+
* Returns undefined if no inverse is defined.
|
|
75
|
+
*/
|
|
76
|
+
getInverseField(entityType: string, fieldName: string): string | undefined;
|
|
77
|
+
/**
|
|
78
|
+
* Gets all scalar field names for an entity
|
|
79
|
+
*/
|
|
80
|
+
getScalarFields(entityType: string): string[];
|
|
81
|
+
/**
|
|
82
|
+
* Gets all relation field names for an entity
|
|
83
|
+
*/
|
|
84
|
+
getRelationFields(entityType: string): string[];
|
|
85
|
+
/**
|
|
86
|
+
* Gets all field names for an entity
|
|
87
|
+
*/
|
|
88
|
+
getAllFields(entityType: string): string[];
|
|
89
|
+
/**
|
|
90
|
+
* Validates that all relation targets exist in the schema.
|
|
91
|
+
* Throws an error if any target is missing.
|
|
92
|
+
*/
|
|
93
|
+
validate(): void;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=SchemaRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaRegistry.d.ts","sourceRoot":"","sources":["../../src/schema/SchemaRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EACX,eAAe,EACf,QAAQ,EAGR,YAAY,EACZ,gBAAgB,EAChB,MAAM,YAAY,CAAA;AAEnB;;;GAGG;AACH,qBAAa,cAAc,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAC1F,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA8B;gBAE7C,UAAU,EAAE,gBAAgB,CAAC,OAAO,CAAC;IAQjD;;;OAGG;IACH,MAAM,CAAC,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,cAAc;IAoCnE;;OAEG;IACH,cAAc,IAAI,MAAM,EAAE;IAI1B;;OAEG;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAItC;;OAEG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI7D;;OAEG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAMxE;;;OAGG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS;IAMnF;;;OAGG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAMtE;;;OAGG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAMxE;;;OAGG;IACH,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAW5E;;;OAGG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAWhF;;OAEG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAI1D;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAIxD;;OAEG;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAIzD;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAKxD;;;OAGG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAQ1E;;OAEG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAS7C;;OAEG;IACH,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAS/C;;OAEG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAO1C;;;OAGG;IACH,QAAQ,IAAI,IAAI;CAchB"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { type RelationType, type ScalarFieldDef, type HasOneRelationDef, type HasManyRelationDef, type FieldDef, type EntitySchemaDef, type SchemaDefinition, type InferModel, type InferEntityNames, type EntityDef, type InferEntityDef, scalar, enumScalar, type EnumFieldDef, hasOne, hasMany, defineSchema, entityDef, roleEntityDef, } from './types.js';
|
|
2
|
+
export { type UnionToIntersection, type RoleNames, type CommonEntity, type EntityForRoles, type ResolveEntity, type SingleRoleMap, type DefaultRole, DEFAULT_ROLE, } from './roles.js';
|
|
3
|
+
export { SchemaRegistry } from './SchemaRegistry.js';
|
|
4
|
+
export { type SchemaColumnType, type SchemaColumn, type SchemaRelationOrderBy, type OwningRelation, type InverseRelation, type SchemaRelation, type SchemaField, type SchemaEntity, type SchemaEnum, type ContemberSchemaStore, type RawContemberSchema, ContemberSchema, } from './ContemberSchema.js';
|
|
5
|
+
export { SchemaLoader, type SchemaLoaderClient } from './SchemaLoader.js';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schema/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,MAAM,EACN,UAAU,EACV,KAAK,YAAY,EACjB,MAAM,EACN,OAAO,EACP,YAAY,EACZ,SAAS,EACT,aAAa,GACb,MAAM,YAAY,CAAA;AAEnB,OAAO,EACN,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,YAAY,GACZ,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,OAAO,EACN,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,eAAe,GACf,MAAM,sBAAsB,CAAA;AAE7B,OAAO,EAAE,YAAY,EAAE,KAAK,kBAAkB,EAAE,MAAM,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role-aware type utilities for bindx.
|
|
3
|
+
*
|
|
4
|
+
* The role system allows per-role field access control at the type level.
|
|
5
|
+
* Default (no role) = narrowest scope (fields ALL roles can access).
|
|
6
|
+
* Specifying roles = expanding scope (union of capabilities for those roles).
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Converts a union type to an intersection type.
|
|
10
|
+
* Used to merge field sets from multiple roles.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* UnionToIntersection<{ a: 1 } | { b: 2 }> = { a: 1 } & { b: 2 }
|
|
14
|
+
*/
|
|
15
|
+
export type UnionToIntersection<U> = (U extends unknown ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
|
|
16
|
+
/**
|
|
17
|
+
* Extracts all role names from a role map.
|
|
18
|
+
*/
|
|
19
|
+
export type RoleNames<TRoleMap extends Record<string, object>> = keyof TRoleMap & string;
|
|
20
|
+
/**
|
|
21
|
+
* Default entity type — the narrowest scope.
|
|
22
|
+
* Returns a union of all role entity types, so only common fields are accessible via keyof.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* CommonEntity<{ admin: { id: string; secret: string }; public: { id: string } }>
|
|
26
|
+
* // = { id: string; secret: string } | { id: string }
|
|
27
|
+
* // Only `id` is accessible (common to all roles)
|
|
28
|
+
*/
|
|
29
|
+
export type CommonEntity<TRoleMap extends Record<string, object>> = TRoleMap[keyof TRoleMap];
|
|
30
|
+
/**
|
|
31
|
+
* Entity type for specific roles — expanded scope.
|
|
32
|
+
* Returns an intersection of the specified roles' entity types,
|
|
33
|
+
* giving access to all fields from any of those roles.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* EntityForRoles<{ admin: { id: string; secret: string }; editor: { id: string; notes: string } }, 'admin'>
|
|
37
|
+
* // = { id: string; secret: string }
|
|
38
|
+
*
|
|
39
|
+
* EntityForRoles<{ admin: { id: string; secret: string }; editor: { id: string; notes: string } }, 'admin' | 'editor'>
|
|
40
|
+
* // = { id: string; secret: string } & { id: string; notes: string }
|
|
41
|
+
* // = { id: string; secret: string; notes: string }
|
|
42
|
+
*/
|
|
43
|
+
export type EntityForRoles<TRoleMap extends Record<string, object>, TRoles extends keyof TRoleMap> = UnionToIntersection<TRoleMap[TRoles]> & object;
|
|
44
|
+
/**
|
|
45
|
+
* Resolves the entity type based on whether roles are specified.
|
|
46
|
+
* - No roles (TRoles = never): returns CommonEntity (narrowest)
|
|
47
|
+
* - With roles: returns EntityForRoles (expanded)
|
|
48
|
+
*/
|
|
49
|
+
export type ResolveEntity<TRoleMap extends Record<string, object>, TRoles extends string> = [TRoles] extends [never] ? CommonEntity<TRoleMap> : EntityForRoles<TRoleMap, TRoles & keyof TRoleMap>;
|
|
50
|
+
/**
|
|
51
|
+
* Sentinel role name used when no ACL roles are defined.
|
|
52
|
+
* entityDef<Article>('Article') wraps as { _default: Article }.
|
|
53
|
+
*/
|
|
54
|
+
export declare const DEFAULT_ROLE: "_default";
|
|
55
|
+
export type DefaultRole = typeof DEFAULT_ROLE;
|
|
56
|
+
/**
|
|
57
|
+
* Wraps a single entity type as a single-role map with the _default role.
|
|
58
|
+
*/
|
|
59
|
+
export type SingleRoleMap<TEntity extends object> = {
|
|
60
|
+
readonly [K in DefaultRole]: TEntity;
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=roles.d.ts.map
|