@cfast/actions 0.1.3 → 0.2.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/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { C as ClientDescriptor, S as Serializable } from './types-CJpjon5s.js';
1
+ import { C as ClientDescriptor, S as Serializable } from './types-C1PGA5l3.js';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
  import { Form } from 'react-router';
4
4
  import { ComponentProps, ReactNode } from 'react';
@@ -9,8 +9,16 @@ import '@cfast/permissions';
9
9
  * Creates a ClientDescriptor for use in client code without importing
10
10
  * server modules. The action names must match the keys passed to
11
11
  * `composeActions` or the single action name from `createAction`.
12
+ *
13
+ * Pass a `readonly` tuple (`as const`) to get compile-time type-checking
14
+ * of action names throughout the client code:
15
+ *
16
+ * ```ts
17
+ * const client = clientDescriptor(["create", "delete"] as const);
18
+ * // client is ClientDescriptor<readonly ["create", "delete"]>
19
+ * ```
12
20
  */
13
- declare function clientDescriptor(actionNames: readonly string[]): ClientDescriptor;
21
+ declare function clientDescriptor<const TNames extends readonly string[]>(actionNames: TNames): ClientDescriptor<TNames>;
14
22
  type ActionHookResult = {
15
23
  permitted: boolean;
16
24
  invisible: boolean;
@@ -20,7 +28,9 @@ type ActionHookResult = {
20
28
  data: unknown | undefined;
21
29
  error: unknown | undefined;
22
30
  };
23
- declare function useActions(descriptor: ClientDescriptor): Record<string, (input?: Serializable) => ActionHookResult>;
31
+ declare function useActions<const TNames extends readonly string[]>(descriptor: ClientDescriptor<TNames>): {
32
+ [K in TNames[number]]: (input?: Serializable) => ActionHookResult;
33
+ };
24
34
 
25
35
  type ActionFormProps = Omit<ComponentProps<typeof Form>, "children" | "action"> & {
26
36
  /** Object with `_action` key and input fields to inject as hidden inputs. */
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Grant, PermissionDescriptor } from '@cfast/permissions';
2
- import { A as ActionPermissionStatus, a as ActionServices, b as ActionsConfig, O as OperationsFn, c as ActionDefinition, d as ComposedActions } from './types-CJpjon5s.js';
3
- export { e as ActionContext, f as ActionPermissionsMap, C as ClientDescriptor, D as DispatchArgs, R as RequestArgs, S as Serializable } from './types-CJpjon5s.js';
2
+ import { A as ActionPermissionStatus, a as ActionServices, b as ActionsConfig, O as OperationsFn, c as ActionDefinition, d as ComposedActions } from './types-C1PGA5l3.js';
3
+ export { e as ActionContext, f as ActionPermissionsMap, C as ClientDescriptor, D as DispatchArgs, R as RequestArgs, S as Serializable } from './types-C1PGA5l3.js';
4
4
  import '@cfast/db';
5
5
 
6
6
  /**
@@ -223,11 +223,11 @@ type ActionPermissionsMap = Record<string, ActionPermissionStatus>;
223
223
  * Created by {@link ActionDefinition.client} or {@link ComposedActions.client}.
224
224
  * Contains the action names and the key used to read permission data from loader results.
225
225
  */
226
- type ClientDescriptor = {
226
+ type ClientDescriptor<TNames extends readonly string[] = readonly string[]> = {
227
227
  /** Brand field to distinguish this type at the type level. */
228
228
  _brand: "ActionClientDescriptor";
229
229
  /** The list of action names this descriptor covers. */
230
- actionNames: readonly string[];
230
+ actionNames: TNames;
231
231
  /** The loader-data key where {@link ActionPermissionsMap} is stored. */
232
232
  permissionsKey: string;
233
233
  };
package/llms.txt CHANGED
@@ -68,9 +68,31 @@ type ActionPermissionsMap = Record<string, ActionPermissionStatus>;
68
68
 
69
69
  ### Client (`@cfast/actions/client`)
70
70
 
71
+ #### Type-safe `clientDescriptor()` and `useActions()`
72
+
73
+ `clientDescriptor()` now uses `const` type parameters to infer the literal tuple
74
+ type from the action names array. `useActions()` returns a mapped type keyed by
75
+ those literal names instead of `Record<string, ...>`, giving compile-time
76
+ autocomplete and error checking on action names.
77
+
71
78
  ```typescript
72
- function useActions(descriptor: ClientDescriptor): Record<string, (input?: Serializable) => ActionHookResult>;
73
- function clientDescriptor(actionNames: readonly string[]): ClientDescriptor;
79
+ // Type-safe: actions.create and actions.delete are typed, typos are caught
80
+ const client = clientDescriptor(["create", "delete"]);
81
+ // client is ClientDescriptor<readonly ["create", "delete"]>
82
+
83
+ const actions = useActions(client);
84
+ // actions is { create: (input?) => ActionHookResult; delete: (input?) => ActionHookResult }
85
+ // actions.creat → TypeScript error (typo caught at compile time)
86
+ ```
87
+
88
+ ```typescript
89
+ function useActions<const TNames extends readonly string[]>(
90
+ descriptor: ClientDescriptor<TNames>,
91
+ ): { [K in TNames[number]]: (input?: Serializable) => ActionHookResult };
92
+
93
+ function clientDescriptor<const TNames extends readonly string[]>(
94
+ actionNames: TNames,
95
+ ): ClientDescriptor<TNames>;
74
96
 
75
97
  function ActionForm(props: ActionFormProps): JSX.Element;
76
98
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cfast/actions",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "description": "Multi-action routes and permission-aware action definitions for React Router",
5
5
  "keywords": [
6
6
  "cfast",
@@ -59,7 +59,7 @@
59
59
  "tsup": "^8",
60
60
  "typescript": "^5.7",
61
61
  "vitest": "^4.1.0",
62
- "@cfast/db": "0.4.1",
62
+ "@cfast/db": "0.5.0",
63
63
  "@cfast/permissions": "0.5.1"
64
64
  },
65
65
  "scripts": {