@kellanjs/actioncraft 0.1.0 → 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.
Files changed (87) hide show
  1. package/README.md +411 -302
  2. package/dist/actioncraft-error.d.ts +23 -0
  3. package/dist/actioncraft-error.js +60 -0
  4. package/dist/actioncraft-error.js.map +1 -0
  5. package/dist/actioncraft-prev.d.ts +93 -0
  6. package/dist/actioncraft-prev.js +387 -0
  7. package/dist/actioncraft-prev.js.map +1 -0
  8. package/dist/actioncraft.d.ts +94 -44
  9. package/dist/actioncraft.js +281 -55
  10. package/dist/actioncraft.js.map +1 -1
  11. package/dist/api.d.ts +49 -0
  12. package/dist/api.js +84 -0
  13. package/dist/api.js.map +1 -0
  14. package/dist/classes/action-builder.d.ts +59 -0
  15. package/dist/classes/action-builder.js +95 -0
  16. package/dist/classes/action-builder.js.map +1 -0
  17. package/dist/classes/craft-builder.d.ts +66 -0
  18. package/dist/classes/craft-builder.js +129 -0
  19. package/dist/classes/craft-builder.js.map +1 -0
  20. package/dist/classes/crafter.d.ts +66 -0
  21. package/dist/classes/crafter.js +129 -0
  22. package/dist/classes/crafter.js.map +1 -0
  23. package/dist/classes/error.d.ts +23 -0
  24. package/dist/classes/error.js +60 -0
  25. package/dist/classes/error.js.map +1 -0
  26. package/dist/classes/executor/callbacks.d.ts +6 -0
  27. package/dist/classes/executor/callbacks.js +20 -0
  28. package/dist/classes/executor/callbacks.js.map +1 -0
  29. package/dist/classes/executor/errors.d.ts +29 -0
  30. package/dist/classes/executor/errors.js +114 -0
  31. package/dist/classes/executor/errors.js.map +1 -0
  32. package/dist/classes/executor/executor.d.ts +68 -0
  33. package/dist/classes/executor/executor.js +391 -0
  34. package/dist/classes/executor/executor.js.map +1 -0
  35. package/dist/classes/executor/logging.d.ts +2 -0
  36. package/dist/classes/executor/logging.js +8 -0
  37. package/dist/classes/executor/logging.js.map +1 -0
  38. package/dist/classes/executor/transformation.d.ts +17 -0
  39. package/dist/classes/executor/transformation.js +43 -0
  40. package/dist/classes/executor/transformation.js.map +1 -0
  41. package/dist/classes/executor/validation.d.ts +16 -0
  42. package/dist/classes/executor/validation.js +70 -0
  43. package/dist/classes/executor/validation.js.map +1 -0
  44. package/dist/classes/executor.d.ts +64 -0
  45. package/dist/classes/executor.js +354 -0
  46. package/dist/classes/executor.js.map +1 -0
  47. package/dist/classes/internal.d.ts +10 -0
  48. package/dist/classes/internal.js +5 -0
  49. package/dist/classes/internal.js.map +1 -0
  50. package/dist/core/errors.d.ts +2 -2
  51. package/dist/core/errors.js +5 -5
  52. package/dist/core/errors.js.map +1 -1
  53. package/dist/core/logging.d.ts +1 -1
  54. package/dist/core/transformation.d.ts +2 -2
  55. package/dist/core/validation.d.ts +4 -4
  56. package/dist/core/validation.js +14 -14
  57. package/dist/core/validation.js.map +1 -1
  58. package/dist/craft.d.ts +29 -0
  59. package/dist/craft.js +62 -0
  60. package/dist/craft.js.map +1 -0
  61. package/dist/error.d.ts +21 -6
  62. package/dist/error.js +59 -10
  63. package/dist/error.js.map +1 -1
  64. package/dist/index.d.ts +4 -3
  65. package/dist/index.js +4 -3
  66. package/dist/index.js.map +1 -1
  67. package/dist/initial.d.ts +14 -0
  68. package/dist/initial.js +47 -0
  69. package/dist/initial.js.map +1 -0
  70. package/dist/types/actions.d.ts +67 -25
  71. package/dist/types/builder.d.ts +92 -0
  72. package/dist/types/builder.js +2 -0
  73. package/dist/types/builder.js.map +1 -0
  74. package/dist/types/crafter.d.ts +87 -0
  75. package/dist/types/crafter.js +2 -0
  76. package/dist/types/crafter.js.map +1 -0
  77. package/dist/types/errors.d.ts +25 -17
  78. package/dist/types/inference.d.ts +41 -8
  79. package/dist/types/result.d.ts +8 -14
  80. package/dist/types/result.js +36 -4
  81. package/dist/types/result.js.map +1 -1
  82. package/dist/types/schemas.d.ts +7 -7
  83. package/dist/types/shared.d.ts +14 -6
  84. package/dist/utils.d.ts +30 -6
  85. package/dist/utils.js +68 -8
  86. package/dist/utils.js.map +1 -1
  87. package/package.json +3 -3
package/dist/craft.js ADDED
@@ -0,0 +1,62 @@
1
+ import { Crafter } from "./classes/crafter.js";
2
+ import { Executor } from "./classes/executor.js";
3
+ /**
4
+ * One of two entry points to the Actioncraft system.
5
+ * It provides you with an empty Crafter instance on which you can call any of the fluent
6
+ * Crafter methods to configure and define your action.
7
+ *
8
+ * Example Usage:
9
+ * ```ts
10
+ * const myAction = craft(async (action) => {
11
+ * return action
12
+ * .config(...)
13
+ * .schemas(...)
14
+ * .errors(...)
15
+ * .handler(...)
16
+ * .callbacks(...)
17
+ * });
18
+ * ```
19
+ *
20
+ * @param craftFn - The function that the user passes to `craft()` in order to build an action.
21
+ * @returns The fully-typed server action function that can be used in your app.
22
+ */
23
+ export function craft(craftFn) {
24
+ const crafter = craftFn(new Crafter({}, {}, {}, {}, undefined));
25
+ // Handle async crafter functions
26
+ if (crafter instanceof Promise) {
27
+ return _craftAsync(crafter);
28
+ }
29
+ // Handle sync crafter functions
30
+ const executor = new Executor(crafter);
31
+ const craftedAction = executor.craft();
32
+ return craftedAction;
33
+ }
34
+ /**
35
+ * Internal helper function to handle async craft functions.
36
+ * Encapsulates the logic for creating async actions and preserving metadata.
37
+ */
38
+ function _craftAsync(crafterPromise) {
39
+ // Resolve the crafter once and cache the resulting action to ensure consistent IDs
40
+ const actionPromise = crafterPromise.then((resolvedCrafter) => {
41
+ const executor = new Executor(resolvedCrafter);
42
+ return executor.craft();
43
+ });
44
+ // For async craft functions, we need to return an async action
45
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
+ const asyncAction = (async (...args) => {
47
+ // Wait for the cached action to be ready
48
+ const craftedAction = await actionPromise;
49
+ // Call the action with the user's arguments
50
+ return craftedAction(...args);
51
+ });
52
+ // We need to preserve the config and ID for the initial() function to work
53
+ // We'll use the same cached action to ensure consistent metadata
54
+ actionPromise.then((craftedAction) => {
55
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
56
+ asyncAction.__ac_config = craftedAction.__ac_config;
57
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
58
+ asyncAction.__ac_id = craftedAction.__ac_id;
59
+ });
60
+ return asyncAction;
61
+ }
62
+ //# sourceMappingURL=craft.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"craft.js","sourceRoot":"","sources":["../src/craft.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAkCjD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,KAAK,CAOnB,OAA+D;IAE/D,MAAM,OAAO,GAAG,OAAO,CACrB,IAAI,OAAO,CACT,EAAmB,EACnB,EAA2B,EAC3B,EAA2B,EAC3B,EAA2B,EAC3B,SAAS,CACV,CACF,CAAC;IAEF,iCAAiC;IACjC,IAAI,OAAO,YAAY,OAAO,EAAE,CAAC;QAC/B,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,gCAAgC;IAChC,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,OAAO,CAAC,CAAC;IACvC,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;IAEvC,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW,CAOlB,cAEC;IAED,mFAAmF;IACnF,MAAM,aAAa,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,eAAe,EAAE,EAAE;QAC5D,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,eAAe,CAAC,CAAC;QAC/C,OAAO,QAAQ,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,+DAA+D;IAC/D,8DAA8D;IAC9D,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;QAC5C,yCAAyC;QACzC,MAAM,aAAa,GAAG,MAAM,aAAa,CAAC;QAE1C,4CAA4C;QAC5C,OAAO,aAAa,CAAC,GAAG,IAAI,CAAC,CAAC;IAChC,CAAC,CAAqD,CAAC;IAEvD,2EAA2E;IAC3E,iEAAiE;IACjE,aAAa,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,EAAE;QACnC,8DAA8D;QAC7D,WAAmB,CAAC,WAAW,GAAI,aAAqB,CAAC,WAAW,CAAC;QACtE,8DAA8D;QAC7D,WAAmB,CAAC,OAAO,GAAI,aAAqB,CAAC,OAAO,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,OAAO,WAAW,CAAC;AACrB,CAAC"}
package/dist/error.d.ts CHANGED
@@ -3,14 +3,29 @@ import type { BaseError } from "./types/errors.js";
3
3
  import type { InferErrors } from "./types/inference.js";
4
4
  /**
5
5
  * Error wrapper that provides standard Error semantics while preserving
6
- * the original ActionCraft error data in the cause property.
6
+ * the original Actioncraft error data in the cause property.
7
7
  */
8
- export declare class ActionCraftError<TErrorData extends BaseError = BaseError> extends Error {
8
+ export declare class ActioncraftError<TErrorData extends BaseError = BaseError> extends Error {
9
9
  readonly cause: TErrorData;
10
- constructor(errorData: TErrorData);
10
+ readonly actionId?: string;
11
+ constructor(errorData: TErrorData, actionId?: string);
11
12
  }
12
13
  /**
13
- * Type guard to check if an error is an ActionCraftError with the action's error types.
14
- * The action parameter is used purely for type inference.
14
+ * Type guard to check if an error is an ActioncraftError.
15
+ *
16
+ * When called with just an error, performs basic structural validation.
17
+ * When called with an error and action, performs verified action ID checking.
18
+ *
19
+ * @param error - The unknown error to check
20
+ * @param action - Optional action for verified checking and type inference
21
+ * @returns Type predicate indicating if error is ActioncraftError
15
22
  */
16
- export declare function isActionCraftError<TAction extends CraftedAction<any, any, any, any>>(error: unknown, _action: TAction): error is ActionCraftError<InferErrors<TAction>>;
23
+ export declare function isActioncraftError<TAction extends CraftedAction<any, any, any, any>>(error: unknown, action?: TAction): error is ActioncraftError<TAction extends undefined ? BaseError : InferErrors<TAction>>;
24
+ /**
25
+ * Utility to extract the action ID from a crafted action.
26
+ * Useful for debugging and logging purposes.
27
+ *
28
+ * @param action - The crafted action
29
+ * @returns The action ID if available, undefined otherwise
30
+ */
31
+ export declare function getActionId<TAction extends CraftedAction<any, any, any, any>>(action: TAction): string | undefined;
package/dist/error.js CHANGED
@@ -1,22 +1,71 @@
1
1
  /**
2
2
  * Error wrapper that provides standard Error semantics while preserving
3
- * the original ActionCraft error data in the cause property.
3
+ * the original Actioncraft error data in the cause property.
4
4
  */
5
- export class ActionCraftError extends Error {
5
+ export class ActioncraftError extends Error {
6
6
  cause;
7
- constructor(errorData) {
8
- super(`ActionCraft Error: ${errorData.type}${"message" in errorData ? ` - ${errorData.message}` : ""}`);
9
- this.name = "ActionCraftError";
7
+ actionId;
8
+ constructor(errorData, actionId) {
9
+ super(`Actioncraft Error: ${errorData.type}${"message" in errorData ? ` - ${errorData.message}` : ""}`);
10
+ this.name = "ActioncraftError";
10
11
  this.cause = errorData;
12
+ this.actionId = actionId;
11
13
  // Ensure proper prototype chain for instanceof checks
12
- Object.setPrototypeOf(this, ActionCraftError.prototype);
14
+ Object.setPrototypeOf(this, ActioncraftError.prototype);
13
15
  }
14
16
  }
15
17
  /**
16
- * Type guard to check if an error is an ActionCraftError with the action's error types.
17
- * The action parameter is used purely for type inference.
18
+ * Type guard to check if an error is an ActioncraftError.
19
+ *
20
+ * When called with just an error, performs basic structural validation.
21
+ * When called with an error and action, performs verified action ID checking.
22
+ *
23
+ * @param error - The unknown error to check
24
+ * @param action - Optional action for verified checking and type inference
25
+ * @returns Type predicate indicating if error is ActioncraftError
18
26
  */
19
- export function isActionCraftError(error, _action) {
20
- return error instanceof ActionCraftError;
27
+ export function isActioncraftError(error, action) {
28
+ if (!(error instanceof ActioncraftError)) {
29
+ return false;
30
+ }
31
+ // Verify the cause property exists and has the expected BaseError structure
32
+ const cause = error.cause;
33
+ if (!cause || typeof cause !== "object") {
34
+ return false;
35
+ }
36
+ // Verify the cause has a type property that's a string (required by BaseError)
37
+ if (!("type" in cause) || typeof cause.type !== "string") {
38
+ return false;
39
+ }
40
+ // If message exists, it should be a string (optional in BaseError)
41
+ if ("message" in cause &&
42
+ cause.message !== undefined &&
43
+ typeof cause.message !== "string") {
44
+ return false;
45
+ }
46
+ // If no action provided, just do structural validation
47
+ if (!action) {
48
+ return true;
49
+ }
50
+ // If action provided, verify the action ID matches
51
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
+ const actionId = action.__ac_id;
53
+ // Both action and error must have IDs for verification to be possible
54
+ if (!actionId || !error.actionId) {
55
+ return false;
56
+ }
57
+ // Check if the error's action ID matches the action's ID
58
+ return error.actionId === actionId;
59
+ }
60
+ /**
61
+ * Utility to extract the action ID from a crafted action.
62
+ * Useful for debugging and logging purposes.
63
+ *
64
+ * @param action - The crafted action
65
+ * @returns The action ID if available, undefined otherwise
66
+ */
67
+ export function getActionId(action) {
68
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
+ return action.__ac_id;
21
70
  }
22
71
  //# sourceMappingURL=error.js.map
package/dist/error.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,OAAO,gBAEX,SAAQ,KAAK;IACY,KAAK,CAAa;IAE3C,YAAY,SAAqB;QAC/B,KAAK,CACH,sBAAsB,SAAS,CAAC,IAAI,GAClC,SAAS,IAAI,SAAS,CAAC,CAAC,CAAC,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EACvD,EAAE,CACH,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QAEvB,sDAAsD;QACtD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC1D,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAIhC,KAAc,EACd,OAAgB;IAEhB,OAAO,KAAK,YAAY,gBAAgB,CAAC;AAC3C,CAAC"}
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,OAAO,gBAEX,SAAQ,KAAK;IACY,KAAK,CAAa;IAC3B,QAAQ,CAAU;IAElC,YAAY,SAAqB,EAAE,QAAiB;QAClD,KAAK,CACH,sBAAsB,SAAS,CAAC,IAAI,GAClC,SAAS,IAAI,SAAS,CAAC,CAAC,CAAC,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EACvD,EAAE,CACH,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEzB,sDAAsD;QACtD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC1D,CAAC;CACF;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAIhC,KAAc,EACd,MAAgB;IAIhB,IAAI,CAAC,CAAC,KAAK,YAAY,gBAAgB,CAAC,EAAE,CAAC;QACzC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,4EAA4E;IAC5E,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC1B,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,+EAA+E;IAC/E,IAAI,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACzD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,mEAAmE;IACnE,IACE,SAAS,IAAI,KAAK;QAClB,KAAK,CAAC,OAAO,KAAK,SAAS;QAC3B,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,EACjC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,uDAAuD;IACvD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mDAAmD;IACnD,8DAA8D;IAC9D,MAAM,QAAQ,GAAI,MAAc,CAAC,OAA6B,CAAC;IAE/D,sEAAsE;IACtE,IAAI,CAAC,QAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,yDAAyD;IACzD,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,CAAC;AACrC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAGzB,MAAe;IACf,8DAA8D;IAC9D,OAAQ,MAAc,CAAC,OAA6B,CAAC;AACvD,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- export { create, initial } from "./actioncraft.js";
2
- export { unwrap, throwable } from "./utils.js";
3
- export { ActionCraftError, isActionCraftError } from "./error.js";
1
+ export { craft } from "./classes/craft-builder.js";
2
+ export { action } from "./classes/action-builder.js";
3
+ export { unwrap, throwable, initial, getActionId } from "./utils.js";
4
+ export { ActioncraftError, isActioncraftError } from "./classes/error.js";
4
5
  export type { Result, Ok, Err } from "./types/result.js";
5
6
  export { isOk, isErr, ok, err } from "./types/result.js";
6
7
  export type { InferInput, InferResult, InferData, InferErrors, } from "./types/inference.js";
package/dist/index.js CHANGED
@@ -2,8 +2,9 @@
2
2
  // PUBLIC API EXPORTS
3
3
  // ============================================================================
4
4
  // Core Functions
5
- export { create, initial } from "./actioncraft.js";
6
- export { unwrap, throwable } from "./utils.js";
7
- export { ActionCraftError, isActionCraftError } from "./error.js";
5
+ export { craft } from "./classes/craft-builder.js";
6
+ export { action } from "./classes/action-builder.js";
7
+ export { unwrap, throwable, initial, getActionId } from "./utils.js";
8
+ export { ActioncraftError, isActioncraftError } from "./classes/error.js";
8
9
  export { isOk, isErr, ok, err } from "./types/result.js";
9
10
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E,iBAAiB;AACjB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIlE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E,iBAAiB;AACjB,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAI1E,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { InferResult } from "./types/inference.js";
2
+ /**
3
+ * Creates an appropriate initial state for any action based on its configuration.
4
+ * The initial state uses the action's real ID for consistency with actual results.
5
+ *
6
+ * For useActionState actions: returns StatefulApiResult with error and values
7
+ * For functional format actions: returns Result.err() with error
8
+ * For regular actions: returns ApiResult with error
9
+ *
10
+ * Usage:
11
+ * - useActionState: const [state, action] = useActionState(myAction, initial(myAction))
12
+ * - useState: const [state, setState] = useState(initial(myAction))
13
+ */
14
+ export declare function initial<TAction>(action: TAction): InferResult<TAction>;
@@ -0,0 +1,47 @@
1
+ import { EXTERNAL_ERROR_TYPES } from "./types/errors.js";
2
+ import { err } from "./types/result.js";
3
+ /**
4
+ * Creates an appropriate initial state for any action based on its configuration.
5
+ * The initial state uses the action's real ID for consistency with actual results.
6
+ *
7
+ * For useActionState actions: returns StatefulApiResult with error and values
8
+ * For functional format actions: returns Result.err() with error
9
+ * For regular actions: returns ApiResult with error
10
+ *
11
+ * Usage:
12
+ * - useActionState: const [state, action] = useActionState(myAction, initial(myAction))
13
+ * - useState: const [state, setState] = useState(initial(myAction))
14
+ */
15
+ export function initial(action) {
16
+ const error = {
17
+ type: EXTERNAL_ERROR_TYPES.INITIAL_STATE,
18
+ message: "Action has not been executed yet",
19
+ };
20
+ // Attempt to read the action ID created during craft()
21
+ const actionId =
22
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
+ action?.__ac_id ?? "unknown";
24
+ // Attempt to read the Actioncraft config attached during craft()
25
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
+ const cfg = action?.__ac_config;
27
+ // Functional format -> Result<_, _>
28
+ if (cfg?.resultFormat === "functional") {
29
+ return err(error, actionId);
30
+ }
31
+ // useActionState enabled -> StatefulApiResult
32
+ if (cfg?.useActionState) {
33
+ return {
34
+ success: false,
35
+ error,
36
+ values: undefined,
37
+ __ac_id: actionId,
38
+ };
39
+ }
40
+ // Default ApiResult shape
41
+ return {
42
+ success: false,
43
+ error,
44
+ __ac_id: actionId,
45
+ };
46
+ }
47
+ //# sourceMappingURL=initial.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"initial.js","sourceRoot":"","sources":["../src/initial.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAExC;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,OAAO,CAAU,MAAe;IAC9C,MAAM,KAAK,GAAG;QACZ,IAAI,EAAE,oBAAoB,CAAC,aAAa;QACxC,OAAO,EAAE,kCAAkC;KACnC,CAAC;IAEX,uDAAuD;IACvD,MAAM,QAAQ;IACZ,8DAA8D;IAC5D,MAAc,EAAE,OAA8B,IAAI,SAAS,CAAC;IAEhE,iEAAiE;IACjE,8DAA8D;IAC9D,MAAM,GAAG,GAAI,MAAc,EAAE,WAEhB,CAAC;IAEd,oCAAoC;IACpC,IAAI,GAAG,EAAE,YAAY,KAAK,YAAY,EAAE,CAAC;QACvC,OAAO,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAoC,CAAC;IACjE,CAAC;IAED,8CAA8C;IAC9C,IAAI,GAAG,EAAE,cAAc,EAAE,CAAC;QACxB,OAAO;YACL,OAAO,EAAE,KAAc;YACvB,KAAK;YACL,MAAM,EAAE,SAAS;YACjB,OAAO,EAAE,QAAQ;SACiB,CAAC;IACvC,CAAC;IAED,0BAA0B;IAC1B,OAAO;QACL,OAAO,EAAE,KAAc;QACvB,KAAK;QACL,OAAO,EAAE,QAAQ;KACiB,CAAC;AACvC,CAAC"}
@@ -1,47 +1,47 @@
1
1
  import type { StandardSchemaV1 } from "../standard-schema.js";
2
- import type { CrafterConfig, CrafterSchemas, CrafterErrors } from "./config.js";
3
- import type { ErrorFunctions, InferUserDefinedErrorTypes, PossibleErrors } from "./errors.js";
2
+ import type { Config, Schemas, Errors } from "./builder.js";
3
+ import type { ErrorFunctions, InferUserDefinedErrorTypes, PossibleErrors, InferInputValidationErrorFormat, NoInputSchemaError } from "./errors.js";
4
4
  import type { Result, Ok, Err } from "./result.js";
5
- import type { InferValidatedInput, InferRawBindArgs, InferValidatedBindArgs, InferRawInputTuple } from "./schemas.js";
6
- import type { ApiResult, ActionImplMetadata, StatefulApiResult } from "./shared.js";
5
+ import type { InferValidatedInput, InferRawBindArgs, InferValidatedBindArgs, InferRawInputTuple, InferRawInput } from "./schemas.js";
6
+ import type { ApiResult, HandlerMetadata, StatefulApiResult } from "./shared.js";
7
7
  /**
8
- * Extracts the success data type from an action implementation function.
8
+ * Extracts the success data type from a handler function.
9
9
  */
10
- export type InferDataFromActionImpl<TFn> = TFn extends (...args: any[]) => any ? Awaited<ReturnType<TFn>> extends infer TReturn ? TReturn extends Ok<infer U> ? U : TReturn extends Err<unknown> | undefined ? never : TReturn : never : never;
10
+ export type InferDataFromHandler<TFn> = TFn extends (...args: any[]) => any ? Awaited<ReturnType<TFn>> extends infer TReturn ? TReturn extends Ok<infer U> ? U : TReturn extends Err<unknown> | undefined ? never : TReturn : never : never;
11
11
  /**
12
- * Parameters passed to action implementation functions.
12
+ * Parameters passed to handler functions.
13
13
  */
14
- export type ActionImplParams<TConfig extends CrafterConfig, TSchemas extends CrafterSchemas, TErrors extends CrafterErrors, TData> = {
14
+ export type HandlerParams<TConfig extends Config, TSchemas extends Schemas, TErrors extends Errors, TData> = {
15
15
  /** Validated input data after schema validation */
16
16
  input: InferValidatedInput<TSchemas>;
17
17
  /** Validated bind arguments after schema validation */
18
18
  bindArgs: InferValidatedBindArgs<TSchemas>;
19
19
  /** Helper functions for returning typed errors */
20
20
  errors: ErrorFunctions<TErrors>;
21
- /** Action metadata for debugging and logging */
22
- metadata: ActionImplMetadata<TConfig, TSchemas, TErrors, TData>;
21
+ /** Handler metadata for debugging and logging */
22
+ metadata: HandlerMetadata<TConfig, TSchemas, TErrors, TData>;
23
23
  };
24
24
  /**
25
- * Action implementation function signature.
25
+ * Handler function signature.
26
26
  * Can return ok(data), errors.yourError(), raw data, or null.
27
27
  * Returning undefined is treated as an error.
28
28
  */
29
- export type ActionImpl<TConfig extends CrafterConfig, TSchemas extends CrafterSchemas, TErrors extends CrafterErrors, TData> = (params: ActionImplParams<TConfig, TSchemas, TErrors, TData>) => Promise<Result<TData, InferUserDefinedErrorTypes<TErrors>> | TData | undefined>;
29
+ export type Handler<TConfig extends Config, TSchemas extends Schemas, TErrors extends Errors, TData> = (params: HandlerParams<TConfig, TSchemas, TErrors, TData>) => Promise<Result<TData, InferUserDefinedErrorTypes<TErrors>> | TData | undefined>;
30
30
  /**
31
- * Arguments that the action implementation accepts.
31
+ * Arguments that the handler accepts.
32
32
  * Differs based on useActionState configuration.
33
33
  */
34
- export type InferActionImplArgs<TConfig extends CrafterConfig, TSchemas extends CrafterSchemas, TErrors extends CrafterErrors, TData> = TConfig extends {
34
+ export type InferHandlerArgs<TConfig extends Config, TSchemas extends Schemas, TErrors extends Errors, TData> = TConfig extends {
35
35
  useActionState: true;
36
36
  } ? StatefulActionArgs<TConfig, TSchemas, TErrors, TData> : StatelessActionArgs<TSchemas>;
37
37
  /**
38
38
  * Action compatible with React's useActionState hook.
39
39
  */
40
- export type StatefulAction<TConfig extends CrafterConfig, TSchemas extends CrafterSchemas, TErrors extends CrafterErrors, TData> = (...args: StatefulActionArgs<TConfig, TSchemas, TErrors, TData>) => Promise<InferCraftedActionResult<TConfig, TSchemas, TErrors, TData>>;
40
+ export type StatefulAction<TConfig extends Config, TSchemas extends Schemas, TErrors extends Errors, TData> = (...args: StatefulActionArgs<TConfig, TSchemas, TErrors, TData>) => Promise<InferCraftedActionResult<TConfig, TSchemas, TErrors, TData>>;
41
41
  /**
42
42
  * Arguments for stateful actions: bind args, previous state, then input.
43
43
  */
44
- export type StatefulActionArgs<TConfig extends CrafterConfig, TSchemas extends CrafterSchemas, TErrors extends CrafterErrors, TData> = [
44
+ export type StatefulActionArgs<TConfig extends Config, TSchemas extends Schemas, TErrors extends Errors, TData> = [
45
45
  ...InferRawBindArgs<TSchemas>,
46
46
  InferPrevStateArg<TConfig, TSchemas, TErrors, TData>,
47
47
  ...InferRawInputTuple<TSchemas>
@@ -49,7 +49,7 @@ export type StatefulActionArgs<TConfig extends CrafterConfig, TSchemas extends C
49
49
  /**
50
50
  * Previous state parameter for useActionState.
51
51
  */
52
- export type InferPrevStateArg<TConfig extends CrafterConfig, TSchemas extends CrafterSchemas, TErrors extends CrafterErrors, TData> = TConfig extends {
52
+ export type InferPrevStateArg<TConfig extends Config, TSchemas extends Schemas, TErrors extends Errors, TData> = TConfig extends {
53
53
  useActionState: true;
54
54
  } ? StatefulApiResult<TData, PossibleErrors<TErrors, TConfig, TSchemas>, InferSerializedSuccessValues<TSchemas>, InferSerializedErrorValues<TSchemas>> : never;
55
55
  /**
@@ -83,36 +83,78 @@ type _ValuesWithFallback<T> = {
83
83
  /**
84
84
  * Form values available when an action succeeds.
85
85
  */
86
- export type InferSerializedSuccessValues<TSchemas extends CrafterSchemas> = TSchemas extends {
86
+ export type InferSerializedSuccessValues<TSchemas extends Schemas> = TSchemas extends {
87
87
  inputSchema: StandardSchemaV1;
88
88
  } ? StandardSchemaV1.InferOutput<TSchemas["inputSchema"]> extends Record<string, unknown> ? Record<string, string | string[]> & _ValuesWithFallback<_SafePlainObjectLike<StandardSchemaV1.InferOutput<TSchemas["inputSchema"]>>> : StandardSchemaV1.InferOutput<TSchemas["inputSchema"]> : unknown;
89
89
  /**
90
90
  * Form values available when an action fails.
91
91
  */
92
- export type InferSerializedErrorValues<TSchemas extends CrafterSchemas> = TSchemas extends {
92
+ export type InferSerializedErrorValues<TSchemas extends Schemas> = TSchemas extends {
93
93
  inputSchema: StandardSchemaV1;
94
94
  } ? Record<string, string | string[]> & _ValuesWithFallback<_SafePlainObjectLike<StandardSchemaV1.InferInput<TSchemas["inputSchema"]>>> : Record<string, string | string[]>;
95
95
  /**
96
96
  * Regular server action that doesn't use useActionState.
97
97
  */
98
- export type StatelessAction<TConfig extends CrafterConfig, TSchemas extends CrafterSchemas, TErrors extends CrafterErrors, TData> = (...args: StatelessActionArgs<TSchemas>) => Promise<InferCraftedActionResult<TConfig, TSchemas, TErrors, TData>>;
98
+ export type StatelessAction<TConfig extends Config, TSchemas extends Schemas, TErrors extends Errors, TData> = (...args: StatelessActionArgs<TSchemas>) => Promise<InferCraftedActionResult<TConfig, TSchemas, TErrors, TData>>;
99
99
  /**
100
100
  * Arguments for stateless actions: bind args followed by input.
101
101
  */
102
- export type StatelessActionArgs<TSchemas extends CrafterSchemas> = [
102
+ export type StatelessActionArgs<TSchemas extends Schemas> = [
103
103
  ...InferRawBindArgs<TSchemas>,
104
104
  ...InferRawInputTuple<TSchemas>
105
105
  ];
106
106
  /**
107
- * Final action function returned by .craft().
107
+ * Type inference utilities available on crafted actions.
108
+ */
109
+ export type CraftedActionInfer<TConfig extends Config, TSchemas extends Schemas, TErrors extends Errors, TData> = {
110
+ /** The raw input type expected by this action */
111
+ Input: InferRawInput<TSchemas>;
112
+ /** The success data type returned by this action's handler */
113
+ Data: TData;
114
+ /** The complete result type returned when calling this action */
115
+ Result: InferCraftedActionResult<TConfig, TSchemas, TErrors, TData>;
116
+ /** The possible error types that can be returned by this action */
117
+ Errors: PossibleErrors<TErrors, TConfig, TSchemas>;
118
+ };
119
+ /**
120
+ * Schema validation result for the $validate method.
121
+ */
122
+ export type ValidationResult<TConfig extends Config, TSchemas extends Schemas> = TSchemas extends {
123
+ inputSchema: unknown;
124
+ } ? {
125
+ success: true;
126
+ data: InferValidatedInput<TSchemas>;
127
+ } | {
128
+ success: false;
129
+ error: InferInputValidationErrorFormat<TConfig>;
130
+ } : {
131
+ success: false;
132
+ error: NoInputSchemaError;
133
+ };
134
+ /**
135
+ * The fully-typed server action function returned by the `craft()` method.
108
136
  */
109
- export type CraftedAction<TConfig extends CrafterConfig, TSchemas extends CrafterSchemas, TErrors extends CrafterErrors, TData> = TConfig extends {
137
+ export type CraftedAction<TConfig extends Config, TSchemas extends Schemas, TErrors extends Errors, TData> = (TConfig extends {
110
138
  useActionState: true;
111
- } ? StatefulAction<TConfig, TSchemas, TErrors, TData> : StatelessAction<TConfig, TSchemas, TErrors, TData>;
139
+ } ? StatefulAction<TConfig, TSchemas, TErrors, TData> : StatelessAction<TConfig, TSchemas, TErrors, TData>) & {
140
+ /**
141
+ * Type inference utilities for extracting types from this action.
142
+ * Use with `typeof action.$Infer.Input` etc.
143
+ */
144
+ $Infer: CraftedActionInfer<TConfig, TSchemas, TErrors, TData>;
145
+ /**
146
+ * Validates input data against this action's input schema without executing the action.
147
+ * Returns a result object indicating success/failure with typed data or errors.
148
+ *
149
+ * @param input - The input data to validate
150
+ * @returns Promise resolving to validation result with success flag and data/error
151
+ */
152
+ $validate(input: InferRawInput<TSchemas>): Promise<ValidationResult<TConfig, TSchemas>>;
153
+ };
112
154
  /**
113
155
  * Result returned when calling a crafted action.
114
156
  */
115
- export type InferCraftedActionResult<TConfig extends CrafterConfig, TSchemas extends CrafterSchemas, TErrors extends CrafterErrors, TData> = TConfig extends {
157
+ export type InferCraftedActionResult<TConfig extends Config, TSchemas extends Schemas, TErrors extends Errors, TData> = TConfig extends {
116
158
  useActionState: true;
117
159
  } ? StatefulApiResult<TData, PossibleErrors<TErrors, TConfig, TSchemas>, InferSerializedSuccessValues<TSchemas>, InferSerializedErrorValues<TSchemas>> : TConfig extends {
118
160
  resultFormat: "functional";
@@ -0,0 +1,92 @@
1
+ import type { StandardSchemaV1 } from "../standard-schema.js";
2
+ import type { InferCraftedActionResult } from "./actions.js";
3
+ import type { AllPossibleErrors, ErrorDefinition, UserDefinedError } from "./errors.js";
4
+ import type { CallbackMetadata } from "./shared.js";
5
+ /**
6
+ * Custom logging interface for Actioncraft.
7
+ */
8
+ export type Logger = {
9
+ /** Called when callback functions fail */
10
+ error?: (message: string, error: unknown) => void;
11
+ /** Called when Actioncraft detects internal bugs */
12
+ warn?: (message: string, details?: unknown) => void;
13
+ };
14
+ /**
15
+ * Configuration options for crafting actions.
16
+ */
17
+ export type Config = {
18
+ /**
19
+ * Optional name for this action.
20
+ * When provided, error messages will include this identifier to help with debugging.
21
+ */
22
+ actionName?: string;
23
+ /**
24
+ * Result format returned by actions.
25
+ * "api" returns {success, data/error}, "functional" returns {type, value/error}.
26
+ * Ignored when useActionState is enabled.
27
+ * @default "api"
28
+ */
29
+ resultFormat?: "api" | "functional";
30
+ /**
31
+ * Validation error structure.
32
+ * "flattened" returns array of {path, message}, "nested" groups by field.
33
+ * @default "flattened"
34
+ */
35
+ validationErrorFormat?: "flattened" | "nested";
36
+ /**
37
+ * Enables React useActionState compatibility.
38
+ * Action accepts prevState parameter and returns a stateful result.
39
+ * @default false
40
+ */
41
+ useActionState?: boolean;
42
+ /**
43
+ * Custom handler for unexpected thrown errors.
44
+ * Transforms exceptions into structured error objects.
45
+ */
46
+ handleThrownError?: (error: unknown) => UserDefinedError;
47
+ /**
48
+ * Logger for Actioncraft internal events.
49
+ */
50
+ logger?: Logger;
51
+ };
52
+ /**
53
+ * Schema definitions for validating inputs and outputs.
54
+ */
55
+ export type Schemas = {
56
+ /** Validates input values passed to the action */
57
+ inputSchema?: StandardSchemaV1;
58
+ /** Validates success data returned from the action */
59
+ outputSchema?: StandardSchemaV1;
60
+ /** Array of schemas for validating bound arguments */
61
+ bindSchemas?: readonly StandardSchemaV1[];
62
+ };
63
+ /**
64
+ * Custom error types that actions can return.
65
+ * Each property is a function that creates a typed error object.
66
+ */
67
+ export type Errors = Record<string, ErrorDefinition>;
68
+ /**
69
+ * Lifecycle hooks that run during action execution.
70
+ * Callback errors are logged but do not affect action results.
71
+ */
72
+ export type Callbacks<TConfig extends Config, TSchemas extends Schemas, TErrors extends Errors, TData> = {
73
+ /** Called when action starts executing, before any validation. */
74
+ onStart?: (params: {
75
+ metadata: CallbackMetadata<TConfig, TSchemas, TErrors, TData>;
76
+ }) => Promise<void> | void;
77
+ /** Called when action fails. */
78
+ onError?: (params: {
79
+ error: AllPossibleErrors<TErrors, TConfig, TSchemas>;
80
+ metadata: CallbackMetadata<TConfig, TSchemas, TErrors, TData>;
81
+ }) => Promise<void> | void;
82
+ /** Called when action succeeds. */
83
+ onSuccess?: (params: {
84
+ data: TData;
85
+ metadata: CallbackMetadata<TConfig, TSchemas, TErrors, TData>;
86
+ }) => Promise<void> | void;
87
+ /** Called after action finishes, regardless of success or failure. */
88
+ onSettled?: (params: {
89
+ result: InferCraftedActionResult<TConfig, TSchemas, TErrors, TData>;
90
+ metadata: CallbackMetadata<TConfig, TSchemas, TErrors, TData>;
91
+ }) => Promise<void> | void;
92
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/types/builder.ts"],"names":[],"mappings":""}
@@ -0,0 +1,87 @@
1
+ import type { StandardSchemaV1 } from "../standard-schema.js";
2
+ import type { InferCraftedActionResult } from "./actions.js";
3
+ import type { AllPossibleErrors, ErrorDefinition, UserDefinedError } from "./errors.js";
4
+ import type { CallbackMetadata } from "./shared.js";
5
+ /**
6
+ * Custom logging interface for Actioncraft.
7
+ */
8
+ export type Logger = {
9
+ /** Called when callback functions fail */
10
+ error?: (message: string, error: unknown) => void;
11
+ /** Called when Actioncraft detects internal bugs */
12
+ warn?: (message: string, details?: unknown) => void;
13
+ };
14
+ /**
15
+ * Configuration options for crafting actions.
16
+ */
17
+ export type Config = {
18
+ /**
19
+ * Result format returned by actions.
20
+ * "api" returns {success, data/error}, "functional" returns {type, value/error}.
21
+ * Ignored when useActionState is enabled.
22
+ * @default "api"
23
+ */
24
+ resultFormat?: "api" | "functional";
25
+ /**
26
+ * Validation error structure.
27
+ * "flattened" returns array of {path, message}, "nested" groups by field.
28
+ * @default "flattened"
29
+ */
30
+ validationErrorFormat?: "flattened" | "nested";
31
+ /**
32
+ * Enables React useActionState compatibility.
33
+ * Action accepts prevState parameter and returns a stateful result.
34
+ * @default false
35
+ */
36
+ useActionState?: boolean;
37
+ /**
38
+ * Custom handler for unexpected thrown errors.
39
+ * Transforms exceptions into structured error objects.
40
+ */
41
+ handleThrownError?: (error: unknown) => UserDefinedError;
42
+ /**
43
+ * Logger for Actioncraft internal events.
44
+ */
45
+ logger?: Logger;
46
+ };
47
+ /**
48
+ * Schema definitions for validating inputs and outputs.
49
+ */
50
+ export type Schemas = {
51
+ /** Validates input values passed to the action */
52
+ inputSchema?: StandardSchemaV1;
53
+ /** Validates success data returned from the action */
54
+ outputSchema?: StandardSchemaV1;
55
+ /** Array of schemas for validating bound arguments */
56
+ bindSchemas?: readonly StandardSchemaV1[];
57
+ };
58
+ /**
59
+ * Custom error types that actions can return.
60
+ * Each property is a function that creates a typed error object.
61
+ */
62
+ export type Errors = Record<string, ErrorDefinition>;
63
+ /**
64
+ * Lifecycle hooks that run during action execution.
65
+ * Callback errors are logged but do not affect action results.
66
+ */
67
+ export type Callbacks<TConfig extends Config, TSchemas extends Schemas, TErrors extends Errors, TData> = {
68
+ /** Called when action starts executing, before any validation. */
69
+ onStart?: (params: {
70
+ metadata: CallbackMetadata<TConfig, TSchemas, TErrors, TData>;
71
+ }) => Promise<void> | void;
72
+ /** Called when action fails. */
73
+ onError?: (params: {
74
+ error: AllPossibleErrors<TErrors, TConfig, TSchemas>;
75
+ metadata: CallbackMetadata<TConfig, TSchemas, TErrors, TData>;
76
+ }) => Promise<void> | void;
77
+ /** Called when action succeeds. */
78
+ onSuccess?: (params: {
79
+ data: TData;
80
+ metadata: CallbackMetadata<TConfig, TSchemas, TErrors, TData>;
81
+ }) => Promise<void> | void;
82
+ /** Called after action finishes, regardless of success or failure. */
83
+ onSettled?: (params: {
84
+ result: InferCraftedActionResult<TConfig, TSchemas, TErrors, TData>;
85
+ metadata: CallbackMetadata<TConfig, TSchemas, TErrors, TData>;
86
+ }) => Promise<void> | void;
87
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=crafter.js.map