@loj-lang/rdsl-runtime 0.5.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/README.md +19 -0
- package/dist/components/Badge.d.ts +6 -0
- package/dist/components/Badge.d.ts.map +1 -0
- package/dist/components/Badge.js +5 -0
- package/dist/components/ConfirmDialog.d.ts +8 -0
- package/dist/components/ConfirmDialog.d.ts.map +1 -0
- package/dist/components/ConfirmDialog.js +11 -0
- package/dist/components/DataTable.d.ts +34 -0
- package/dist/components/DataTable.d.ts.map +1 -0
- package/dist/components/DataTable.js +58 -0
- package/dist/components/FilterBar.d.ts +13 -0
- package/dist/components/FilterBar.d.ts.map +1 -0
- package/dist/components/FilterBar.js +41 -0
- package/dist/components/FormField.d.ts +22 -0
- package/dist/components/FormField.d.ts.map +1 -0
- package/dist/components/FormField.js +66 -0
- package/dist/components/GroupedDataTable.d.ts +26 -0
- package/dist/components/GroupedDataTable.d.ts.map +1 -0
- package/dist/components/GroupedDataTable.js +67 -0
- package/dist/components/Pagination.d.ts +7 -0
- package/dist/components/Pagination.d.ts.map +1 -0
- package/dist/components/Pagination.js +12 -0
- package/dist/components/PivotDataTable.d.ts +25 -0
- package/dist/components/PivotDataTable.d.ts.map +1 -0
- package/dist/components/PivotDataTable.js +72 -0
- package/dist/components/Tag.d.ts +6 -0
- package/dist/components/Tag.d.ts.map +1 -0
- package/dist/components/Tag.js +5 -0
- package/dist/components/WorkflowSummary.d.ts +5 -0
- package/dist/components/WorkflowSummary.d.ts.map +1 -0
- package/dist/components/WorkflowSummary.js +17 -0
- package/dist/hooks/navigation.d.ts +20 -0
- package/dist/hooks/navigation.d.ts.map +1 -0
- package/dist/hooks/navigation.js +135 -0
- package/dist/hooks/resourceClient.d.ts +36 -0
- package/dist/hooks/resourceClient.d.ts.map +1 -0
- package/dist/hooks/resourceClient.js +259 -0
- package/dist/hooks/resourceStore.d.ts +25 -0
- package/dist/hooks/resourceStore.d.ts.map +1 -0
- package/dist/hooks/resourceStore.js +164 -0
- package/dist/hooks/resourceTarget.d.ts +2 -0
- package/dist/hooks/resourceTarget.d.ts.map +1 -0
- package/dist/hooks/resourceTarget.js +22 -0
- package/dist/hooks/useAuth.d.ts +16 -0
- package/dist/hooks/useAuth.d.ts.map +1 -0
- package/dist/hooks/useAuth.js +20 -0
- package/dist/hooks/useCollectionView.d.ts +28 -0
- package/dist/hooks/useCollectionView.d.ts.map +1 -0
- package/dist/hooks/useCollectionView.js +73 -0
- package/dist/hooks/useDocumentMetadata.d.ts +13 -0
- package/dist/hooks/useDocumentMetadata.d.ts.map +1 -0
- package/dist/hooks/useDocumentMetadata.js +111 -0
- package/dist/hooks/useGroupedCollectionView.d.ts +26 -0
- package/dist/hooks/useGroupedCollectionView.d.ts.map +1 -0
- package/dist/hooks/useGroupedCollectionView.js +82 -0
- package/dist/hooks/useReadModel.d.ts +16 -0
- package/dist/hooks/useReadModel.d.ts.map +1 -0
- package/dist/hooks/useReadModel.js +104 -0
- package/dist/hooks/useResource.d.ts +36 -0
- package/dist/hooks/useResource.d.ts.map +1 -0
- package/dist/hooks/useResource.js +69 -0
- package/dist/hooks/useToast.d.ts +18 -0
- package/dist/hooks/useToast.d.ts.map +1 -0
- package/dist/hooks/useToast.js +31 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/policies/can.d.ts +15 -0
- package/dist/policies/can.d.ts.map +1 -0
- package/dist/policies/can.js +160 -0
- package/package.json +55 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export { DataTable } from './components/DataTable.js';
|
|
2
|
+
export type { DataTableAction, DataTableColumn, DataTableProps, SortState } from './components/DataTable.js';
|
|
3
|
+
export { GroupedDataTable } from './components/GroupedDataTable.js';
|
|
4
|
+
export type { GroupedDataTableGroup, GroupedDataTableProps } from './components/GroupedDataTable.js';
|
|
5
|
+
export { PivotDataTable } from './components/PivotDataTable.js';
|
|
6
|
+
export type { PivotDataTableGroup, PivotDataTableProps } from './components/PivotDataTable.js';
|
|
7
|
+
export { FilterBar } from './components/FilterBar.js';
|
|
8
|
+
export type { FilterBarProps, FilterField } from './components/FilterBar.js';
|
|
9
|
+
export { Pagination } from './components/Pagination.js';
|
|
10
|
+
export type { PaginationProps } from './components/Pagination.js';
|
|
11
|
+
export { FormField } from './components/FormField.js';
|
|
12
|
+
export type { FieldSchema, FormFieldProps } from './components/FormField.js';
|
|
13
|
+
export { WorkflowSummary } from './components/WorkflowSummary.js';
|
|
14
|
+
export type { WorkflowSummaryProps, WorkflowSummaryStep } from './components/WorkflowSummary.js';
|
|
15
|
+
export { Tag } from './components/Tag.js';
|
|
16
|
+
export type { TagProps } from './components/Tag.js';
|
|
17
|
+
export { Badge } from './components/Badge.js';
|
|
18
|
+
export type { BadgeProps } from './components/Badge.js';
|
|
19
|
+
export { ConfirmDialog } from './components/ConfirmDialog.js';
|
|
20
|
+
export type { ConfirmDialogProps } from './components/ConfirmDialog.js';
|
|
21
|
+
export { useResource } from './hooks/useResource.js';
|
|
22
|
+
export type { ResourcePaginationState, UseResourceOptions, UseResourceResult } from './hooks/useResource.js';
|
|
23
|
+
export { useReadModel } from './hooks/useReadModel.js';
|
|
24
|
+
export type { UseReadModelOptions, UseReadModelResult } from './hooks/useReadModel.js';
|
|
25
|
+
export { useCollectionView } from './hooks/useCollectionView.js';
|
|
26
|
+
export type { CollectionPaginationState, CollectionSortState, UseCollectionViewOptions, UseCollectionViewResult, } from './hooks/useCollectionView.js';
|
|
27
|
+
export { useGroupedCollectionView } from './hooks/useGroupedCollectionView.js';
|
|
28
|
+
export type { GroupedCollectionViewGroup, UseGroupedCollectionViewOptions, UseGroupedCollectionViewResult, } from './hooks/useGroupedCollectionView.js';
|
|
29
|
+
export { createFetchResourceClient, createMemoryResourceClient, ResourceProvider, useResourceClient, } from './hooks/resourceClient.js';
|
|
30
|
+
export type { FetchResourceClientOptions, ResourceClient, ResourceProviderProps, } from './hooks/resourceClient.js';
|
|
31
|
+
export { useToast, ToastProvider } from './hooks/useToast.js';
|
|
32
|
+
export { resolveToastMessage } from './hooks/useToast.js';
|
|
33
|
+
export type { ToastApi, ToastMessage, ToastMessageDescriptor, ToastMessageValue } from './hooks/useToast.js';
|
|
34
|
+
export { useAuth, AuthProvider } from './hooks/useAuth.js';
|
|
35
|
+
export type { AuthState, AuthUser } from './hooks/useAuth.js';
|
|
36
|
+
export { useDocumentMetadata } from './hooks/useDocumentMetadata.js';
|
|
37
|
+
export type { DocumentMetadata } from './hooks/useDocumentMetadata.js';
|
|
38
|
+
export { configureAppBasePath, getConfiguredAppBasePath, getCurrentAppHref, getCurrentAppPathname, getLocationSearchParams, getLocationSearchValues, normalizeAppBasePath, prefixAppBasePath, replaceLocationSearchValues, getSanitizedReturnTo, sanitizeAppLocalHref, stripAppBasePath, } from './hooks/navigation.js';
|
|
39
|
+
export { can } from './policies/can.js';
|
|
40
|
+
export { evaluatePolicyExpr, firstPolicyFailure, matchesPolicyRule, resolvePolicyMessage } from './policies/can.js';
|
|
41
|
+
export type { PolicyContext } from './policies/can.js';
|
|
42
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export { DataTable } from './components/DataTable.js';
|
|
2
|
+
export { GroupedDataTable } from './components/GroupedDataTable.js';
|
|
3
|
+
export { PivotDataTable } from './components/PivotDataTable.js';
|
|
4
|
+
export { FilterBar } from './components/FilterBar.js';
|
|
5
|
+
export { Pagination } from './components/Pagination.js';
|
|
6
|
+
export { FormField } from './components/FormField.js';
|
|
7
|
+
export { WorkflowSummary } from './components/WorkflowSummary.js';
|
|
8
|
+
export { Tag } from './components/Tag.js';
|
|
9
|
+
export { Badge } from './components/Badge.js';
|
|
10
|
+
export { ConfirmDialog } from './components/ConfirmDialog.js';
|
|
11
|
+
export { useResource } from './hooks/useResource.js';
|
|
12
|
+
export { useReadModel } from './hooks/useReadModel.js';
|
|
13
|
+
export { useCollectionView } from './hooks/useCollectionView.js';
|
|
14
|
+
export { useGroupedCollectionView } from './hooks/useGroupedCollectionView.js';
|
|
15
|
+
export { createFetchResourceClient, createMemoryResourceClient, ResourceProvider, useResourceClient, } from './hooks/resourceClient.js';
|
|
16
|
+
export { useToast, ToastProvider } from './hooks/useToast.js';
|
|
17
|
+
export { resolveToastMessage } from './hooks/useToast.js';
|
|
18
|
+
export { useAuth, AuthProvider } from './hooks/useAuth.js';
|
|
19
|
+
export { useDocumentMetadata } from './hooks/useDocumentMetadata.js';
|
|
20
|
+
export { configureAppBasePath, getConfiguredAppBasePath, getCurrentAppHref, getCurrentAppPathname, getLocationSearchParams, getLocationSearchValues, normalizeAppBasePath, prefixAppBasePath, replaceLocationSearchValues, getSanitizedReturnTo, sanitizeAppLocalHref, stripAppBasePath, } from './hooks/navigation.js';
|
|
21
|
+
export { can } from './policies/can.js';
|
|
22
|
+
export { evaluatePolicyExpr, firstPolicyFailure, matchesPolicyRule, resolvePolicyMessage } from './policies/can.js';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface PolicyContext {
|
|
2
|
+
currentUser?: unknown | null;
|
|
3
|
+
record?: unknown | null;
|
|
4
|
+
formData?: unknown | null;
|
|
5
|
+
item?: unknown | null;
|
|
6
|
+
input?: unknown | null;
|
|
7
|
+
payload?: unknown | null;
|
|
8
|
+
params?: unknown | null;
|
|
9
|
+
}
|
|
10
|
+
export declare function evaluatePolicyExpr(node: unknown, context: PolicyContext): unknown;
|
|
11
|
+
export declare function matchesPolicyRule(rule: unknown, context: PolicyContext): boolean;
|
|
12
|
+
export declare function resolvePolicyMessage(rule: unknown, fallback: string): string;
|
|
13
|
+
export declare function firstPolicyFailure(rules: unknown, context: PolicyContext, fallback: string): string | null;
|
|
14
|
+
export declare function can(rule: unknown, context: PolicyContext): boolean;
|
|
15
|
+
//# sourceMappingURL=can.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"can.d.ts","sourceRoot":"","sources":["../../src/policies/can.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CACzB;AAuID,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAYjF;AAaD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAKhF;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAK5E;AAED,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAUf;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAGlE"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { resolveMessageText } from '@loj-lang/shared-contracts';
|
|
2
|
+
function isBuiltinRule(rule) {
|
|
3
|
+
return typeof rule === 'object'
|
|
4
|
+
&& rule !== null
|
|
5
|
+
&& rule.source === 'builtin'
|
|
6
|
+
&& typeof rule.expr === 'object'
|
|
7
|
+
&& rule.expr !== null;
|
|
8
|
+
}
|
|
9
|
+
function isExprNode(node) {
|
|
10
|
+
return typeof node === 'object'
|
|
11
|
+
&& node !== null
|
|
12
|
+
&& typeof node.type === 'string';
|
|
13
|
+
}
|
|
14
|
+
function isRuleEntryLike(rule) {
|
|
15
|
+
return typeof rule === 'object' && rule !== null;
|
|
16
|
+
}
|
|
17
|
+
function resolveIdentifier(path, context) {
|
|
18
|
+
if (!path || path.length === 0)
|
|
19
|
+
return undefined;
|
|
20
|
+
if (path.length === 1 && /^[A-Z][A-Z0-9_]*$/.test(path[0])) {
|
|
21
|
+
return path[0];
|
|
22
|
+
}
|
|
23
|
+
let current = context;
|
|
24
|
+
for (const segment of path) {
|
|
25
|
+
if (current === null || current === undefined || typeof current !== 'object') {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
current = current[segment];
|
|
29
|
+
}
|
|
30
|
+
return current;
|
|
31
|
+
}
|
|
32
|
+
function isEmptyValue(value) {
|
|
33
|
+
if (value === null || value === undefined || value === '')
|
|
34
|
+
return true;
|
|
35
|
+
if (Array.isArray(value))
|
|
36
|
+
return value.length === 0;
|
|
37
|
+
if (typeof value === 'object')
|
|
38
|
+
return Object.keys(value).length === 0;
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
function evalBuiltin(fn, args) {
|
|
42
|
+
switch (fn) {
|
|
43
|
+
case 'hasRole':
|
|
44
|
+
return typeof args[1] === 'string' && Boolean(args[0]?.role === args[1]);
|
|
45
|
+
case 'isOwner': {
|
|
46
|
+
const user = args[0];
|
|
47
|
+
const record = args[1];
|
|
48
|
+
if (!user || !record)
|
|
49
|
+
return false;
|
|
50
|
+
return user.id === record.id || user.id === record.ownerId || user.id === record.userId;
|
|
51
|
+
}
|
|
52
|
+
case 'isEmpty':
|
|
53
|
+
return isEmptyValue(args[0]);
|
|
54
|
+
case 'isNotEmpty':
|
|
55
|
+
return !isEmptyValue(args[0]);
|
|
56
|
+
case 'count':
|
|
57
|
+
if (Array.isArray(args[0]))
|
|
58
|
+
return args[0].length;
|
|
59
|
+
if (args[0] && typeof args[0] === 'object')
|
|
60
|
+
return Object.keys(args[0]).length;
|
|
61
|
+
return 0;
|
|
62
|
+
default:
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function evaluateExpr(node, context) {
|
|
67
|
+
switch (node.type) {
|
|
68
|
+
case 'literal':
|
|
69
|
+
return node.value;
|
|
70
|
+
case 'identifier':
|
|
71
|
+
return resolveIdentifier(node.path, context);
|
|
72
|
+
case 'member': {
|
|
73
|
+
const object = node.object ? evaluateExpr(node.object, context) : undefined;
|
|
74
|
+
if (!object || typeof object !== 'object' || !node.property)
|
|
75
|
+
return undefined;
|
|
76
|
+
return object[node.property];
|
|
77
|
+
}
|
|
78
|
+
case 'unary':
|
|
79
|
+
return node.op === 'not' ? !Boolean(node.operand ? evaluateExpr(node.operand, context) : undefined) : undefined;
|
|
80
|
+
case 'binary': {
|
|
81
|
+
const left = node.left ? evaluateExpr(node.left, context) : undefined;
|
|
82
|
+
const right = node.right ? evaluateExpr(node.right, context) : undefined;
|
|
83
|
+
switch (node.op) {
|
|
84
|
+
case '==': return left == right;
|
|
85
|
+
case '!=': return left != right;
|
|
86
|
+
case '>': return left > right;
|
|
87
|
+
case '<': return left < right;
|
|
88
|
+
case '>=': return left >= right;
|
|
89
|
+
case '<=': return left <= right;
|
|
90
|
+
case '&&': return Boolean(left) && Boolean(right);
|
|
91
|
+
case '||': return Boolean(left) || Boolean(right);
|
|
92
|
+
case '+': return Number(left ?? 0) + Number(right ?? 0);
|
|
93
|
+
case '-': return Number(left ?? 0) - Number(right ?? 0);
|
|
94
|
+
case '*': return Number(left ?? 0) * Number(right ?? 0);
|
|
95
|
+
case '/': return Number(right ?? 0) === 0 ? undefined : Number(left ?? 0) / Number(right ?? 0);
|
|
96
|
+
default: return undefined;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
case 'call':
|
|
100
|
+
return evalBuiltin(node.fn ?? '', (node.args ?? []).map((arg) => evaluateExpr(arg, context)));
|
|
101
|
+
case 'in': {
|
|
102
|
+
const value = evaluateExpr(node.value, context);
|
|
103
|
+
const list = (node.list ?? []).map((entry) => evaluateExpr(entry, context));
|
|
104
|
+
return list.includes(value);
|
|
105
|
+
}
|
|
106
|
+
default:
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export function evaluatePolicyExpr(node, context) {
|
|
111
|
+
if (isBuiltinRule(node)) {
|
|
112
|
+
return evaluateExpr(node.expr, context);
|
|
113
|
+
}
|
|
114
|
+
if (!isExprNode(node)) {
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
return evaluateExpr(node, context);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return undefined;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function truthy(value) {
|
|
125
|
+
return Boolean(value);
|
|
126
|
+
}
|
|
127
|
+
function anyPolicyRuleMatches(candidate, context) {
|
|
128
|
+
if (!Array.isArray(candidate)) {
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
return candidate.some((entry) => truthy(evaluatePolicyExpr(entry, context)));
|
|
132
|
+
}
|
|
133
|
+
export function matchesPolicyRule(rule, context) {
|
|
134
|
+
if (!isRuleEntryLike(rule)) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
return truthy(evaluatePolicyExpr(rule.when, context)) || anyPolicyRuleMatches(rule.or, context);
|
|
138
|
+
}
|
|
139
|
+
export function resolvePolicyMessage(rule, fallback) {
|
|
140
|
+
if (!isRuleEntryLike(rule)) {
|
|
141
|
+
return fallback;
|
|
142
|
+
}
|
|
143
|
+
return resolveMessageText(rule.message, fallback);
|
|
144
|
+
}
|
|
145
|
+
export function firstPolicyFailure(rules, context, fallback) {
|
|
146
|
+
if (!Array.isArray(rules)) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
for (const rule of rules) {
|
|
150
|
+
if (!matchesPolicyRule(rule, context)) {
|
|
151
|
+
return resolvePolicyMessage(rule, fallback);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
export function can(rule, context) {
|
|
157
|
+
if (!isBuiltinRule(rule))
|
|
158
|
+
return false;
|
|
159
|
+
return truthy(evaluatePolicyExpr(rule, context));
|
|
160
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@loj-lang/rdsl-runtime",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "ReactDSL runtime package for generated React/TypeScript apps",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"license": "Apache-2.0",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=20.19.0"
|
|
14
|
+
},
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public"
|
|
17
|
+
},
|
|
18
|
+
"exports": {
|
|
19
|
+
".": "./dist/index.js",
|
|
20
|
+
"./components/DataTable": "./dist/components/DataTable.js",
|
|
21
|
+
"./components/FilterBar": "./dist/components/FilterBar.js",
|
|
22
|
+
"./components/Pagination": "./dist/components/Pagination.js",
|
|
23
|
+
"./components/FormField": "./dist/components/FormField.js",
|
|
24
|
+
"./components/Tag": "./dist/components/Tag.js",
|
|
25
|
+
"./components/Badge": "./dist/components/Badge.js",
|
|
26
|
+
"./components/ConfirmDialog": "./dist/components/ConfirmDialog.js",
|
|
27
|
+
"./components/GroupedDataTable": "./dist/components/GroupedDataTable.js",
|
|
28
|
+
"./components/PivotDataTable": "./dist/components/PivotDataTable.js",
|
|
29
|
+
"./components/WorkflowSummary": "./dist/components/WorkflowSummary.js",
|
|
30
|
+
"./hooks/navigation": "./dist/hooks/navigation.js",
|
|
31
|
+
"./hooks/useResource": "./dist/hooks/useResource.js",
|
|
32
|
+
"./hooks/useReadModel": "./dist/hooks/useReadModel.js",
|
|
33
|
+
"./hooks/useCollectionView": "./dist/hooks/useCollectionView.js",
|
|
34
|
+
"./hooks/useGroupedCollectionView": "./dist/hooks/useGroupedCollectionView.js",
|
|
35
|
+
"./hooks/resourceClient": "./dist/hooks/resourceClient.js",
|
|
36
|
+
"./hooks/useToast": "./dist/hooks/useToast.js",
|
|
37
|
+
"./hooks/useAuth": "./dist/hooks/useAuth.js",
|
|
38
|
+
"./hooks/useDocumentMetadata": "./dist/hooks/useDocumentMetadata.js",
|
|
39
|
+
"./policies/can": "./dist/policies/can.js"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsc",
|
|
43
|
+
"test": "vitest run"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@loj-lang/shared-contracts": "^0.5.0"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"typescript": "^5.7.0",
|
|
53
|
+
"vitest": "^3.0.0"
|
|
54
|
+
}
|
|
55
|
+
}
|