@kellanjs/actioncraft 0.0.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.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/dist/actioncraft.d.ts +89 -0
  4. package/dist/actioncraft.js +344 -0
  5. package/dist/actioncraft.js.map +1 -0
  6. package/dist/core/callbacks.d.ts +6 -0
  7. package/dist/core/callbacks.js +20 -0
  8. package/dist/core/callbacks.js.map +1 -0
  9. package/dist/core/errors.d.ts +28 -0
  10. package/dist/core/errors.js +101 -0
  11. package/dist/core/errors.js.map +1 -0
  12. package/dist/core/logging.d.ts +6 -0
  13. package/dist/core/logging.js +8 -0
  14. package/dist/core/logging.js.map +1 -0
  15. package/dist/core/transformation.d.ts +17 -0
  16. package/dist/core/transformation.js +43 -0
  17. package/dist/core/transformation.js.map +1 -0
  18. package/dist/core/validation.d.ts +16 -0
  19. package/dist/core/validation.js +70 -0
  20. package/dist/core/validation.js.map +1 -0
  21. package/dist/error.d.ts +16 -0
  22. package/dist/error.js +22 -0
  23. package/dist/error.js.map +1 -0
  24. package/dist/index.d.ts +6 -0
  25. package/dist/index.js +9 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/standard-schema.d.ts +71 -0
  28. package/dist/standard-schema.js +16 -0
  29. package/dist/standard-schema.js.map +1 -0
  30. package/dist/types/actions.d.ts +120 -0
  31. package/dist/types/actions.js +2 -0
  32. package/dist/types/actions.js.map +1 -0
  33. package/dist/types/config.d.ts +80 -0
  34. package/dist/types/config.js +2 -0
  35. package/dist/types/config.js.map +1 -0
  36. package/dist/types/errors.d.ts +207 -0
  37. package/dist/types/errors.js +21 -0
  38. package/dist/types/errors.js.map +1 -0
  39. package/dist/types/inference.d.ts +20 -0
  40. package/dist/types/inference.js +2 -0
  41. package/dist/types/inference.js.map +1 -0
  42. package/dist/types/result.d.ts +72 -0
  43. package/dist/types/result.js +62 -0
  44. package/dist/types/result.js.map +1 -0
  45. package/dist/types/schemas.d.ts +33 -0
  46. package/dist/types/schemas.js +2 -0
  47. package/dist/types/schemas.js.map +1 -0
  48. package/dist/types/shared.d.ts +75 -0
  49. package/dist/types/shared.js +2 -0
  50. package/dist/types/shared.js.map +1 -0
  51. package/dist/utils.d.ts +15 -0
  52. package/dist/utils.js +44 -0
  53. package/dist/utils.js.map +1 -0
  54. package/package.json +74 -0
@@ -0,0 +1,207 @@
1
+ import type { StandardSchemaV1 } from "../standard-schema.js";
2
+ import type { CrafterConfig, CrafterSchemas, CrafterErrors } from "./config.js";
3
+ import type { Result } from "./result.js";
4
+ import type { Prettify } from "./shared.js";
5
+ /**
6
+ * Map of error identifiers that should never be surfaced to clients.
7
+ */
8
+ export declare const INTERNAL_ERROR_TYPES: {
9
+ readonly IMPLICIT_RETURN: "IMPLICIT_RETURN";
10
+ readonly INTERNAL_LOGIC: "INTERNAL_LOGIC";
11
+ readonly OUTPUT_VALIDATION: "OUTPUT_VALIDATION";
12
+ };
13
+ /**
14
+ * Literal union of the keys of `INTERNAL_ERROR_TYPES`
15
+ */
16
+ export type InternalErrorType = (typeof INTERNAL_ERROR_TYPES)[keyof typeof INTERNAL_ERROR_TYPES];
17
+ /**
18
+ * Map of error identifiers that can be surfaced to clients.
19
+ */
20
+ export declare const EXTERNAL_ERROR_TYPES: {
21
+ readonly INITIAL_STATE: "INITIAL_STATE";
22
+ readonly UNHANDLED: "UNHANDLED";
23
+ readonly INPUT_VALIDATION: "INPUT_VALIDATION";
24
+ readonly BIND_ARGS_VALIDATION: "BIND_ARGS_VALIDATION";
25
+ };
26
+ /**
27
+ * Literal union of the keys of `EXTERNAL_ERROR_TYPES`
28
+ */
29
+ export type ExternalErrorType = (typeof EXTERNAL_ERROR_TYPES)[keyof typeof EXTERNAL_ERROR_TYPES];
30
+ /**
31
+ * Base structure for all ActionCraft error objects.
32
+ */
33
+ export type BaseError = {
34
+ type: string;
35
+ message?: string;
36
+ };
37
+ /**
38
+ * Type constraint for custom error objects defined by users.
39
+ */
40
+ export type UserDefinedError = BaseError & Record<string, any>;
41
+ /**
42
+ * Function signature for custom error definitions in .errors() method.
43
+ */
44
+ export type ErrorDefinition = (...args: any[]) => UserDefinedError;
45
+ /**
46
+ * Transforms error definition functions into Result-returning functions.
47
+ */
48
+ export type ErrorDefToResult<T> = T extends (...args: infer P) => any ? (...args: P) => Result<never, ReturnType<T>> : never;
49
+ /**
50
+ * Error when action implementation returns undefined.
51
+ */
52
+ export type ImplicitReturnError = BaseError & {
53
+ type: typeof INTERNAL_ERROR_TYPES.IMPLICIT_RETURN;
54
+ message: "Action implementation must return a value";
55
+ };
56
+ /**
57
+ * Error indicating a bug in the ActionCraft library.
58
+ */
59
+ export type InternalLogicError = BaseError & {
60
+ type: typeof INTERNAL_ERROR_TYPES.INTERNAL_LOGIC;
61
+ message: string;
62
+ };
63
+ /**
64
+ * Marker for initial state in useActionState before any action executes.
65
+ */
66
+ export type InitialStateMarker = BaseError & {
67
+ type: typeof EXTERNAL_ERROR_TYPES.INITIAL_STATE;
68
+ message: "No action has been executed yet";
69
+ };
70
+ /**
71
+ * Error for uncaught exceptions when no custom handler is provided.
72
+ */
73
+ export type UnhandledError = BaseError & {
74
+ type: typeof EXTERNAL_ERROR_TYPES.UNHANDLED;
75
+ message: "An unhandled error occurred";
76
+ };
77
+ /**
78
+ * Base structure for validation errors with nested field organization.
79
+ */
80
+ type NestedValidationError<TType extends string> = BaseError & {
81
+ type: TType;
82
+ message: string;
83
+ formErrors: string[];
84
+ fieldErrors: {
85
+ [path: string]: string[];
86
+ };
87
+ };
88
+ /**
89
+ * Base structure for validation errors with flat issue array.
90
+ */
91
+ type FlattenedValidationError<TType extends string> = BaseError & {
92
+ type: TType;
93
+ message: string;
94
+ issues: {
95
+ path: (string | number)[];
96
+ message: string;
97
+ }[];
98
+ };
99
+ /**
100
+ * Input validation error with nested field structure.
101
+ */
102
+ export type NestedInputValidationError = NestedValidationError<typeof EXTERNAL_ERROR_TYPES.INPUT_VALIDATION>;
103
+ /**
104
+ * Input validation error with flat issue array.
105
+ */
106
+ export type FlattenedInputValidationError = FlattenedValidationError<typeof EXTERNAL_ERROR_TYPES.INPUT_VALIDATION>;
107
+ /**
108
+ * Output validation error with nested field structure.
109
+ */
110
+ export type NestedOutputValidationError = NestedValidationError<typeof INTERNAL_ERROR_TYPES.OUTPUT_VALIDATION>;
111
+ /**
112
+ * Output validation error with flat issue array.
113
+ */
114
+ export type FlattenedOutputValidationError = FlattenedValidationError<typeof INTERNAL_ERROR_TYPES.OUTPUT_VALIDATION>;
115
+ /**
116
+ * Bind arguments validation error with nested field structure.
117
+ */
118
+ export type NestedBindArgsValidationError = NestedValidationError<typeof EXTERNAL_ERROR_TYPES.BIND_ARGS_VALIDATION>;
119
+ /**
120
+ * Bind arguments validation error with flat issue array.
121
+ */
122
+ export type FlattenedBindArgsValidationError = FlattenedValidationError<typeof EXTERNAL_ERROR_TYPES.BIND_ARGS_VALIDATION>;
123
+ /**
124
+ * All possible input validation error formats.
125
+ */
126
+ export type InputValidationError = NestedInputValidationError | FlattenedInputValidationError;
127
+ /**
128
+ * All possible output validation error formats.
129
+ */
130
+ export type OutputValidationError = NestedOutputValidationError | FlattenedOutputValidationError;
131
+ /**
132
+ * All possible bind arguments validation error formats.
133
+ */
134
+ export type BindArgsValidationError = NestedBindArgsValidationError | FlattenedBindArgsValidationError;
135
+ /**
136
+ * All validation error types combined.
137
+ */
138
+ export type ValidationError = InputValidationError | OutputValidationError | BindArgsValidationError;
139
+ /**
140
+ * Base structure for validation errors before type-specific fields.
141
+ */
142
+ export type ValidationErrorFormat = {
143
+ formErrors: string[];
144
+ fieldErrors: Record<string, string[]>;
145
+ } | {
146
+ issues: {
147
+ path: (string | number)[];
148
+ message: string;
149
+ }[];
150
+ };
151
+ /**
152
+ * Error functions object provided to action implementations.
153
+ */
154
+ export type ErrorFunctions<TErrors extends CrafterErrors> = Prettify<{
155
+ [K in keyof TErrors]: ErrorDefToResult<TErrors[K]>;
156
+ }>;
157
+ /**
158
+ * Input validation error format based on configuration.
159
+ */
160
+ export type InferInputValidationErrorFormat<TConfig extends CrafterConfig> = TConfig["validationErrorFormat"] extends "nested" ? NestedInputValidationError : FlattenedInputValidationError;
161
+ /**
162
+ * Output validation error format based on configuration.
163
+ */
164
+ export type InferOutputValidationErrorFormat<TConfig extends CrafterConfig> = TConfig["validationErrorFormat"] extends "nested" ? NestedOutputValidationError : FlattenedOutputValidationError;
165
+ /**
166
+ * Bind arguments validation error format based on configuration.
167
+ */
168
+ export type InferBindArgsValidationErrorFormat<TConfig extends CrafterConfig> = TConfig["validationErrorFormat"] extends "nested" ? NestedBindArgsValidationError : FlattenedBindArgsValidationError;
169
+ /**
170
+ * All error types from user-defined error functions.
171
+ */
172
+ export type InferUserDefinedErrorTypes<TErrors extends CrafterErrors> = {
173
+ [K in keyof TErrors]: ReturnType<TErrors[K]>;
174
+ }[keyof TErrors];
175
+ /**
176
+ * Error type for thrown exceptions based on custom handler configuration.
177
+ */
178
+ export type InferThrownErrorType<TConfig extends CrafterConfig> = TConfig extends {
179
+ handleThrownError: (error: unknown) => infer R;
180
+ } ? R : UnhandledError;
181
+ /**
182
+ * Input validation error type when input schema is present.
183
+ */
184
+ type InferInputValidationErrorType<TConfig extends CrafterConfig, TSchemas extends CrafterSchemas> = TSchemas extends {
185
+ inputSchema: StandardSchemaV1;
186
+ } ? InferInputValidationErrorFormat<TConfig> : never;
187
+ /**
188
+ * Bind arguments validation error type when bind schemas are present.
189
+ */
190
+ type InferBindArgsValidationErrorType<TConfig extends CrafterConfig, TSchemas extends CrafterSchemas> = TSchemas extends {
191
+ bindSchemas: readonly StandardSchemaV1[];
192
+ } ? InferBindArgsValidationErrorFormat<TConfig> : never;
193
+ /**
194
+ * Possible errors that clients should expect when calling an action.
195
+ */
196
+ export type PossibleErrors<TErrors extends CrafterErrors, TConfig extends CrafterConfig, TSchemas extends CrafterSchemas> = InitialStateMarker | InferThrownErrorType<TConfig> | InferInputValidationErrorType<TConfig, TSchemas> | InferBindArgsValidationErrorType<TConfig, TSchemas> | InferUserDefinedErrorTypes<TErrors>;
197
+ /**
198
+ * Output validation error type when output schema is present.
199
+ */
200
+ type InferOutputValidationErrorType<TConfig extends CrafterConfig, TSchemas extends CrafterSchemas> = TSchemas extends {
201
+ outputSchema: StandardSchemaV1;
202
+ } ? InferOutputValidationErrorFormat<TConfig> : never;
203
+ /**
204
+ * All possible errors, both internal and external.
205
+ */
206
+ export type AllPossibleErrors<TErrors extends CrafterErrors, TConfig extends CrafterConfig, TSchemas extends CrafterSchemas> = PossibleErrors<TErrors, TConfig, TSchemas> | ImplicitReturnError | InternalLogicError | InferOutputValidationErrorType<TConfig, TSchemas>;
207
+ export {};
@@ -0,0 +1,21 @@
1
+ // ============================================================================
2
+ // CONSTANTS
3
+ // ============================================================================
4
+ /**
5
+ * Map of error identifiers that should never be surfaced to clients.
6
+ */
7
+ export const INTERNAL_ERROR_TYPES = {
8
+ IMPLICIT_RETURN: "IMPLICIT_RETURN",
9
+ INTERNAL_LOGIC: "INTERNAL_LOGIC",
10
+ OUTPUT_VALIDATION: "OUTPUT_VALIDATION",
11
+ };
12
+ /**
13
+ * Map of error identifiers that can be surfaced to clients.
14
+ */
15
+ export const EXTERNAL_ERROR_TYPES = {
16
+ INITIAL_STATE: "INITIAL_STATE",
17
+ UNHANDLED: "UNHANDLED",
18
+ INPUT_VALIDATION: "INPUT_VALIDATION",
19
+ BIND_ARGS_VALIDATION: "BIND_ARGS_VALIDATION",
20
+ };
21
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/types/errors.ts"],"names":[],"mappings":"AAKA,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,eAAe,EAAE,iBAAiB;IAClC,cAAc,EAAE,gBAAgB;IAChC,iBAAiB,EAAE,mBAAmB;CAC9B,CAAC;AAQX;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,aAAa,EAAE,eAAe;IAC9B,SAAS,EAAE,WAAW;IACtB,gBAAgB,EAAE,kBAAkB;IACpC,oBAAoB,EAAE,sBAAsB;CACpC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { CraftedAction, InferCraftedActionResult } from "./actions.js";
2
+ import type { PossibleErrors } from "./errors.js";
3
+ import type { InferRawInput } from "./schemas.js";
4
+ /**
5
+ * Extracts the raw input type from a crafted action.
6
+ */
7
+ export type InferInput<T> = T extends CraftedAction<infer _TConfig, infer TSchemas, any, // eslint-disable-line @typescript-eslint/no-explicit-any
8
+ any> ? InferRawInput<TSchemas> : never;
9
+ /**
10
+ * Extracts the complete result type from a crafted action.
11
+ */
12
+ export type InferResult<T> = T extends CraftedAction<infer TConfig, infer TSchemas, infer TErrors, infer TData> ? InferCraftedActionResult<TConfig, TSchemas, TErrors, TData> : never;
13
+ /**
14
+ * Extracts the success data type from a crafted action.
15
+ */
16
+ export type InferData<T> = T extends CraftedAction<any, any, any, infer TData> ? TData : never;
17
+ /**
18
+ * Extracts possible error types from a crafted action.
19
+ */
20
+ export type InferErrors<T> = T extends CraftedAction<infer TConfig, infer TSchemas, infer TErrors, any> ? PossibleErrors<TErrors, TConfig, TSchemas> : never;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=inference.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inference.js","sourceRoot":"","sources":["../../src/types/inference.ts"],"names":[],"mappings":""}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * This is the functional Result type that the library uses for all internal logic.
3
+ * The ApiResult format is returned to the client by default, but the action can be
4
+ * configured to return the functional Result type if desired.
5
+ */
6
+ /** A successful result containing a value of type T */
7
+ export type Ok<T> = {
8
+ readonly type: "ok";
9
+ readonly value: T;
10
+ };
11
+ /** A failed result containing an error of type E */
12
+ export type Err<E> = {
13
+ readonly type: "err";
14
+ readonly error: E;
15
+ };
16
+ /**
17
+ * A Result represents an operation that can either succeed (Ok) or fail (Err).
18
+ * This is a serializable alternative to throwing exceptions.
19
+ */
20
+ export type Result<T, E> = Ok<T> | Err<E>;
21
+ /**
22
+ * Creates a successful result.
23
+ * @param value The success value
24
+ * @returns Ok result containing the value
25
+ */
26
+ export declare function ok<T>(value: T): Ok<T>;
27
+ /**
28
+ * Creates a successful result with no value.
29
+ * @returns Ok result with void
30
+ */
31
+ export declare function ok(): Ok<void>;
32
+ /**
33
+ * Creates a failed result.
34
+ * @param error The error value
35
+ * @returns Err result containing the error
36
+ */
37
+ export declare function err<E>(error: E): Err<E>;
38
+ /**
39
+ * Creates a failed result with no error value.
40
+ * @returns Err result with void
41
+ */
42
+ export declare function err(): Err<void>;
43
+ /**
44
+ * Tests if a Result is successful.
45
+ * @param result The Result to check
46
+ * @returns true if result is Ok, false if Err
47
+ */
48
+ export declare function isOk<T, E>(result: Result<T, E>): result is Ok<T>;
49
+ /**
50
+ * Tests if a Result is failed.
51
+ * @param result The Result to check
52
+ * @returns true if result is Err, false if Ok
53
+ */
54
+ export declare function isErr<T, E>(result: Result<T, E>): result is Err<E>;
55
+ /**
56
+ * Tests if an unknown value is a valid Result.
57
+ * @param value The value to check
58
+ * @returns true if value is a Result (Ok or Err), false otherwise
59
+ */
60
+ export declare function isResult<T = unknown, E = unknown>(value: unknown): value is Result<T, E>;
61
+ /**
62
+ * Tests if an unknown value is a valid Ok Result.
63
+ * @param value The value to check
64
+ * @returns true if value is an Ok Result, false otherwise
65
+ */
66
+ export declare function isResultOk<_T = unknown, _E = unknown>(value: unknown): value is Ok<_T>;
67
+ /**
68
+ * Tests if an unknown value is a valid Err Result.
69
+ * @param value The value to check
70
+ * @returns true if value is an Err Result, false otherwise
71
+ */
72
+ export declare function isResultErr<_T = unknown, E = unknown>(value: unknown): value is Err<E>;
@@ -0,0 +1,62 @@
1
+ // ============================================================================
2
+ // Core Result Type
3
+ // ============================================================================
4
+ export function ok(value) {
5
+ return { type: "ok", value: value };
6
+ }
7
+ export function err(error) {
8
+ return { type: "err", error: error };
9
+ }
10
+ /**
11
+ * Tests if a Result is successful.
12
+ * @param result The Result to check
13
+ * @returns true if result is Ok, false if Err
14
+ */
15
+ export function isOk(result) {
16
+ return result.type === "ok";
17
+ }
18
+ /**
19
+ * Tests if a Result is failed.
20
+ * @param result The Result to check
21
+ * @returns true if result is Err, false if Ok
22
+ */
23
+ export function isErr(result) {
24
+ return result.type === "err";
25
+ }
26
+ /**
27
+ * Tests if an unknown value is a valid Result.
28
+ * @param value The value to check
29
+ * @returns true if value is a Result (Ok or Err), false otherwise
30
+ */
31
+ export function isResult(value) {
32
+ return (typeof value === "object" &&
33
+ value !== null &&
34
+ "type" in value &&
35
+ ((value.type === "ok" && "value" in value) ||
36
+ (value.type === "err" && "error" in value)));
37
+ }
38
+ /**
39
+ * Tests if an unknown value is a valid Ok Result.
40
+ * @param value The value to check
41
+ * @returns true if value is an Ok Result, false otherwise
42
+ */
43
+ export function isResultOk(value) {
44
+ return (typeof value === "object" &&
45
+ value !== null &&
46
+ "type" in value &&
47
+ value.type === "ok" &&
48
+ "value" in value);
49
+ }
50
+ /**
51
+ * Tests if an unknown value is a valid Err Result.
52
+ * @param value The value to check
53
+ * @returns true if value is an Err Result, false otherwise
54
+ */
55
+ export function isResultErr(value) {
56
+ return (typeof value === "object" &&
57
+ value !== null &&
58
+ "type" in value &&
59
+ value.type === "err" &&
60
+ "error" in value);
61
+ }
62
+ //# sourceMappingURL=result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../../src/types/result.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AA6B/E,MAAM,UAAU,EAAE,CAAW,KAAS;IACpC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAmC,CAAC;AACvE,CAAC;AAaD,MAAM,UAAU,GAAG,CAAW,KAAS;IACrC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAoC,CAAC;AACzE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAAO,MAAoB;IAC7C,OAAO,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAO,MAAoB;IAC9C,OAAO,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC;AAC/B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CACtB,KAAc;IAEd,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,CAAC;YACxC,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,IAAI,OAAO,IAAI,KAAK,CAAC,CAAC,CAC9C,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CACxB,KAAc;IAEd,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,KAAK,CAAC,IAAI,KAAK,IAAI;QACnB,OAAO,IAAI,KAAK,CACjB,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,KAAc;IAEd,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,MAAM,IAAI,KAAK;QACf,KAAK,CAAC,IAAI,KAAK,KAAK;QACpB,OAAO,IAAI,KAAK,CACjB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { StandardSchemaV1 } from "../standard-schema.js";
2
+ import type { CrafterSchemas } from "./config.js";
3
+ import type { MapSchemasToRawInput, MapSchemasToValidatedOutput } from "./shared.js";
4
+ /**
5
+ * Converts input schema to function parameter tuple for the crafted action.
6
+ */
7
+ export type InferRawInputTuple<TSchemas extends CrafterSchemas> = TSchemas extends {
8
+ inputSchema: StandardSchemaV1;
9
+ } ? [InferRawInput<TSchemas>] : [InferRawInput<TSchemas>?];
10
+ /**
11
+ * Raw input type that users pass to the action before validation.
12
+ */
13
+ export type InferRawInput<TSchemas extends CrafterSchemas> = TSchemas extends {
14
+ inputSchema: StandardSchemaV1;
15
+ } ? StandardSchemaV1.InferInput<TSchemas["inputSchema"]> : unknown;
16
+ /**
17
+ * Validated input type that action implementations receive.
18
+ */
19
+ export type InferValidatedInput<TSchemas extends CrafterSchemas> = TSchemas extends {
20
+ inputSchema: StandardSchemaV1;
21
+ } ? StandardSchemaV1.InferOutput<TSchemas["inputSchema"]> : undefined;
22
+ /**
23
+ * Raw input types for bound arguments before validation.
24
+ */
25
+ export type InferRawBindArgs<TSchemas extends CrafterSchemas> = TSchemas extends {
26
+ bindSchemas: readonly StandardSchemaV1[];
27
+ } ? MapSchemasToRawInput<TSchemas["bindSchemas"]> : [];
28
+ /**
29
+ * Validated output types for bound arguments after validation.
30
+ */
31
+ export type InferValidatedBindArgs<TSchemas extends CrafterSchemas> = TSchemas extends {
32
+ bindSchemas: readonly StandardSchemaV1[];
33
+ } ? MapSchemasToValidatedOutput<TSchemas["bindSchemas"]> : [];
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/types/schemas.ts"],"names":[],"mappings":""}
@@ -0,0 +1,75 @@
1
+ import type { StandardSchemaV1 } from "../standard-schema.js";
2
+ import type { InferPrevStateArg } from "./actions.js";
3
+ import type { CrafterConfig, CrafterErrors, CrafterSchemas } from "./config.js";
4
+ import type { InferData } from "./inference.js";
5
+ import type { InferValidatedInput, InferValidatedBindArgs, InferRawInput } from "./schemas.js";
6
+ /**
7
+ * Expands type aliases for better IDE display.
8
+ */
9
+ export type Prettify<T> = {
10
+ [K in keyof T]: T[K];
11
+ } & {};
12
+ /**
13
+ * Standard success/error result format for actions.
14
+ */
15
+ export type ApiResult<TData, TError> = {
16
+ success: true;
17
+ data: TData;
18
+ } | {
19
+ success: false;
20
+ error: TError;
21
+ };
22
+ /**
23
+ * Result format for actions using useActionState.
24
+ * Includes form values for success and error states.
25
+ */
26
+ export type StatefulApiResult<TData, TError, TSuccessValues = unknown, TErrorValues = TSuccessValues> = {
27
+ success: true;
28
+ data: TData;
29
+ values?: TSuccessValues;
30
+ } | {
31
+ success: false;
32
+ error: TError;
33
+ values?: TErrorValues;
34
+ };
35
+ /**
36
+ * Maps schema array to tuple of raw input types.
37
+ */
38
+ export type MapSchemasToRawInput<T> = T extends readonly [
39
+ infer Head,
40
+ ...infer Tail
41
+ ] ? Head extends StandardSchemaV1 ? [StandardSchemaV1.InferInput<Head>, ...MapSchemasToRawInput<Tail>] : [] : [];
42
+ /**
43
+ * Maps schema array to tuple of validated output types.
44
+ */
45
+ export type MapSchemasToValidatedOutput<T> = T extends readonly [
46
+ infer Head,
47
+ ...infer Tail
48
+ ] ? Head extends StandardSchemaV1 ? [StandardSchemaV1.InferOutput<Head>, ...MapSchemasToValidatedOutput<Tail>] : [] : [];
49
+ /**
50
+ * Base metadata available in action implementations and callbacks.
51
+ */
52
+ export type BaseMetadata<TConfig extends CrafterConfig, TSchemas extends CrafterSchemas, TErrors extends CrafterErrors, TData> = {
53
+ /** Original input before validation */
54
+ rawInput?: InferRawInput<TSchemas>;
55
+ /** Previous result when using useActionState */
56
+ prevState?: InferPrevStateArg<TConfig, TSchemas, TErrors, TData>;
57
+ };
58
+ /**
59
+ * Metadata passed to action implementation functions.
60
+ */
61
+ export type ActionImplMetadata<TConfig extends CrafterConfig, TSchemas extends CrafterSchemas, TErrors extends CrafterErrors, TData> = BaseMetadata<TConfig, TSchemas, TErrors, TData>;
62
+ /**
63
+ * Enhanced metadata passed to lifecycle callbacks.
64
+ */
65
+ export type CallbackMetadata<TConfig extends CrafterConfig, TSchemas extends CrafterSchemas, TErrors extends CrafterErrors, TData> = BaseMetadata<TConfig, TSchemas, TErrors, TData> & {
66
+ /** Input data after validation */
67
+ validatedInput?: InferValidatedInput<TSchemas>;
68
+ /** Bind arguments after validation */
69
+ validatedBindArgs?: InferValidatedBindArgs<TSchemas>;
70
+ };
71
+ /**
72
+ * Converts Result-based action to Exception-based action.
73
+ * Used by the throwable() utility function.
74
+ */
75
+ export type ThrowableAction<TAction> = TAction extends (...args: infer TArgs) => Promise<any> ? (...args: TArgs) => Promise<InferData<TAction>> : never;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/types/shared.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ import type { CraftedAction } from "./types/actions.js";
2
+ import type { BaseError } from "./types/errors.js";
3
+ import type { Result } from "./types/result.js";
4
+ import type { ApiResult, ThrowableAction } from "./types/shared.js";
5
+ /**
6
+ * Unwraps an ActionCraft result, returning the data or throwing an error.
7
+ * Supports both async and sync usage patterns.
8
+ */
9
+ export declare function unwrap<TData, TError extends BaseError>(promiseResult: Promise<ApiResult<TData, TError> | Result<TData, TError>>): Promise<TData>;
10
+ export declare function unwrap<TData, TError extends BaseError>(result: ApiResult<TData, TError> | Result<TData, TError>): TData;
11
+ /**
12
+ * Creates a throwable version of an ActionCraft action.
13
+ * The returned function throws on error instead of returning Result objects.
14
+ */
15
+ export declare function throwable<TAction extends CraftedAction<any, any, any, any>>(action: TAction): ThrowableAction<TAction>;
package/dist/utils.js ADDED
@@ -0,0 +1,44 @@
1
+ import { ActionCraftError } from "./error.js";
2
+ export function unwrap(resultOrPromise) {
3
+ // Handle Promise case
4
+ if (resultOrPromise instanceof Promise) {
5
+ return resultOrPromise.then((result) => _unwrapSync(result));
6
+ }
7
+ // Handle direct result case
8
+ return _unwrapSync(resultOrPromise);
9
+ }
10
+ /**
11
+ * Synchronously unwraps a result, throwing on error.
12
+ */
13
+ function _unwrapSync(result) {
14
+ // Handle api-style results ({ success: true/false })
15
+ if (typeof result === "object" && result !== null && "success" in result) {
16
+ const apiResult = result;
17
+ if (apiResult.success) {
18
+ return apiResult.data;
19
+ }
20
+ throw new ActionCraftError(apiResult.error);
21
+ }
22
+ // Handle functional-style results ({ type: "ok"/"err" })
23
+ if (typeof result === "object" && result !== null && "type" in result) {
24
+ const functionalResult = result;
25
+ if (functionalResult.type === "ok") {
26
+ return functionalResult.value;
27
+ }
28
+ throw new ActionCraftError(functionalResult.error);
29
+ }
30
+ throw new Error("Invalid result format from ActionCraft action");
31
+ }
32
+ /**
33
+ * Creates a throwable version of an ActionCraft action.
34
+ * The returned function throws on error instead of returning Result objects.
35
+ */
36
+ export function throwable(action) {
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+ return (async (...args) => {
39
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
40
+ const result = await action(...args);
41
+ return unwrap(result);
42
+ });
43
+ }
44
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAkB9C,MAAM,UAAU,MAAM,CACpB,eAG6D;IAE7D,sBAAsB;IACtB,IAAI,eAAe,YAAY,OAAO,EAAE,CAAC;QACvC,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,4BAA4B;IAC5B,OAAO,WAAW,CAAC,eAAe,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAClB,MAAwD;IAExD,qDAAqD;IACrD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,SAAS,IAAI,MAAM,EAAE,CAAC;QACzE,MAAM,SAAS,GAAG,MAAkC,CAAC;QACrD,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YACtB,OAAO,SAAS,CAAC,IAAI,CAAC;QACxB,CAAC;QACD,MAAM,IAAI,gBAAgB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;IAED,yDAAyD;IACzD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;QACtE,MAAM,gBAAgB,GAAG,MAA+B,CAAC;QACzD,IAAI,gBAAgB,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;YACnC,OAAO,gBAAgB,CAAC,KAAK,CAAC;QAChC,CAAC;QACD,MAAM,IAAI,gBAAgB,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;AACnE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAGvB,MAAe;IACf,8DAA8D;IAC9D,OAAO,CAAC,KAAK,EAAE,GAAG,IAAW,EAAE,EAAE;QAC/B,8DAA8D;QAC9D,MAAM,MAAM,GAAG,MAAO,MAAc,CAAC,GAAG,IAAI,CAAC,CAAC;QAC9C,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC,CAA6B,CAAC;AACjC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ "name": "@kellanjs/actioncraft",
3
+ "version": "0.0.1",
4
+ "description": "Fluent, type-safe builder for Next.js server actions.",
5
+ "keywords": [
6
+ "next.js",
7
+ "react",
8
+ "server-actions",
9
+ "server-side",
10
+ "useactionstate",
11
+ "typescript",
12
+ "type-safety",
13
+ "type-inference",
14
+ "fluent-api",
15
+ "builder-pattern",
16
+ "schema-validation",
17
+ "validation",
18
+ "error-handling",
19
+ "form-handling",
20
+ "progressive-enhancement",
21
+ "full-stack"
22
+ ],
23
+ "author": "kellanjs",
24
+ "license": "MIT",
25
+ "homepage": "https://github.com/kellanjs/actioncraft",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/kellanjs/actioncraft.git"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/kellanjs/actioncraft/issues"
32
+ },
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
+ "type": "module",
37
+ "main": "dist/index.js",
38
+ "files": [
39
+ "dist"
40
+ ],
41
+ "scripts": {
42
+ "dev": "vitest",
43
+ "build": "tsc",
44
+ "lint": "eslint .",
45
+ "test": "vitest run",
46
+ "format": "prettier --write .",
47
+ "check-format": "prettier --check .",
48
+ "check-exports": "attw --pack . --ignore-rules=cjs-resolves-to-esm",
49
+ "ci": "npm run lint && npm run build && npm run check-format && npm run check-exports && npm run test"
50
+ },
51
+ "peerDependencies": {
52
+ "next": "^15.0.0",
53
+ "react": "^19.0.0"
54
+ },
55
+ "peerDependenciesMeta": {
56
+ "react": {
57
+ "optional": true
58
+ }
59
+ },
60
+ "devDependencies": {
61
+ "@arethetypeswrong/cli": "^0.18.2",
62
+ "@eslint/js": "^9.30.1",
63
+ "@trivago/prettier-plugin-sort-imports": "^5.2.2",
64
+ "eslint": "^9.30.1",
65
+ "next": "^15.0.0",
66
+ "prettier": "^3.6.2",
67
+ "react": "^19.0.0",
68
+ "typescript": "^5.8.3",
69
+ "typescript-eslint": "^8.35.1",
70
+ "vitest": "^3.2.4",
71
+ "zod": "^3.25.74",
72
+ "zod-form-data": "^3.0.0"
73
+ }
74
+ }