@cfast/actions 0.3.0 → 0.3.1

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/client.d.ts CHANGED
@@ -32,6 +32,28 @@ declare function useActions<const TNames extends readonly string[]>(descriptor:
32
32
  [K in TNames[number]]: (input?: Serializable) => ActionHookResult;
33
33
  };
34
34
 
35
+ /** Permission methods added to items with `_can`. */
36
+ type CfastItemMethods = {
37
+ canRead: () => ActionHookResult;
38
+ canCreate: () => ActionHookResult;
39
+ canEdit: () => ActionHookResult;
40
+ canDelete: () => ActionHookResult;
41
+ };
42
+ /** An item with `_can` gets permission methods mixed in. */
43
+ type CfastItem<T> = T & CfastItemMethods;
44
+ /** A collection gets `canAdd()` plus each item gets permission methods. */
45
+ type CfastCollection<T> = CfastItem<T>[] & {
46
+ canAdd: () => ActionHookResult;
47
+ };
48
+ /**
49
+ * Transforms a loader return type:
50
+ * - Arrays of objects with `_can` -> {@link CfastCollection}
51
+ * - Objects with `_can` -> {@link CfastItem}
52
+ * - Other values -> unchanged
53
+ */
54
+ type CfastLoaderData<T> = {
55
+ [K in keyof T]: T[K] extends (infer U)[] ? U extends Record<string, unknown> ? CfastCollection<U> : T[K] : T[K] extends Record<string, unknown> ? CfastItem<T[K]> : T[K];
56
+ };
35
57
  /**
36
58
  * Client hook that replaces `useLoaderData()` for routes using `cfastJson()`.
37
59
  *
@@ -62,7 +84,7 @@ declare function useActions<const TNames extends readonly string[]>(descriptor:
62
84
  * documents[0].canDelete() // -> ActionHookResult
63
85
  * ```
64
86
  */
65
- declare function useCfastLoader<T extends (...args: any[]) => any = () => Record<string, unknown>>(): ReturnType<T> extends Promise<infer R> ? R : ReturnType<T>;
87
+ declare function useCfastLoader<T extends (...args: any[]) => any = () => Record<string, unknown>>(): CfastLoaderData<ReturnType<T> extends Promise<infer R> ? R : ReturnType<T>>;
66
88
 
67
89
  type ActionFormProps = Omit<ComponentProps<typeof Form>, "children" | "action"> & {
68
90
  /** Object with `_action` key and input fields to inject as hidden inputs. */
@@ -89,4 +111,4 @@ type ActionFormProps = Omit<ComponentProps<typeof Form>, "children" | "action">
89
111
  */
90
112
  declare function ActionForm({ action, children, ...formProps }: ActionFormProps): react_jsx_runtime.JSX.Element;
91
113
 
92
- export { ActionForm, type ActionHookResult, ClientDescriptor, clientDescriptor, useActions, useCfastLoader };
114
+ export { ActionForm, type ActionHookResult, type CfastCollection, type CfastItem, type CfastItemMethods, type CfastLoaderData, ClientDescriptor, clientDescriptor, useActions, useCfastLoader };
package/llms.txt CHANGED
@@ -128,7 +128,7 @@ type ActionFormProps = Omit<ComponentProps<typeof Form>, "children" | "action">
128
128
  ```
129
129
 
130
130
  #### `useCfastLoader<T>()`
131
- Client hook that replaces `useLoaderData()` for routes using `cfastJson()`. Returns the same data but wraps arrays and objects that have `_can` with permission helper methods.
131
+ Client hook that replaces `useLoaderData()` for routes using `cfastJson()`. Returns the same data but wraps arrays and objects that have `_can` with permission helper methods. The return type is `CfastLoaderData<...>`, which automatically adds permission methods to the TypeScript types so consumers get full autocomplete without local type helpers.
132
132
 
133
133
  ```typescript
134
134
  import { useCfastLoader } from "@cfast/actions/client";
@@ -157,6 +157,46 @@ Wrapping rules:
157
157
 
158
158
  All `can*()` methods return `ActionHookResult` with `permitted`, `invisible`, `reason`, `submit` (no-op), `pending` (false), `data`, `error`.
159
159
 
160
+ #### Permission helper types
161
+
162
+ Exported from `@cfast/actions/client` for consumers who need to annotate variables or build custom abstractions:
163
+
164
+ ```typescript
165
+ import type {
166
+ CfastItem,
167
+ CfastCollection,
168
+ CfastItemMethods,
169
+ CfastLoaderData,
170
+ } from "@cfast/actions/client";
171
+
172
+ /** Permission methods added to items with _can */
173
+ type CfastItemMethods = {
174
+ canRead: () => ActionHookResult;
175
+ canCreate: () => ActionHookResult;
176
+ canEdit: () => ActionHookResult;
177
+ canDelete: () => ActionHookResult;
178
+ };
179
+
180
+ /** An item with _can gets permission methods mixed in */
181
+ type CfastItem<T> = T & CfastItemMethods;
182
+
183
+ /** A collection gets canAdd() plus each item gets permission methods */
184
+ type CfastCollection<T> = CfastItem<T>[] & {
185
+ canAdd: () => ActionHookResult;
186
+ };
187
+
188
+ /** Transforms a loader return type -- arrays become CfastCollection, objects become CfastItem, primitives pass through */
189
+ type CfastLoaderData<T> = {
190
+ [K in keyof T]: T[K] extends (infer U)[]
191
+ ? U extends Record<string, unknown>
192
+ ? CfastCollection<U>
193
+ : T[K]
194
+ : T[K] extends Record<string, unknown>
195
+ ? CfastItem<T[K]>
196
+ : T[K];
197
+ };
198
+ ```
199
+
160
200
  `ActionForm` is a form wrapper that auto-injects hidden fields from an action descriptor object. Replaces manual `<input type="hidden">` patterns when using `composeActions`.
161
201
 
162
202
  ```tsx
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cfast/actions",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Multi-action routes and permission-aware action definitions for React Router",
5
5
  "keywords": [
6
6
  "cfast",