@nice-code/action 0.0.15
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/build/index.js +3753 -0
- package/build/types/ActionDomain/NiceActionDomain.d.ts +67 -0
- package/build/types/ActionDomain/NiceActionDomain.types.d.ts +79 -0
- package/build/types/ActionDomain/createActionDomain.d.ts +5 -0
- package/build/types/ActionRequestResponse/ActionRequester/NiceActionRequester.d.ts +31 -0
- package/build/types/ActionRequestResponse/ActionResponder/NiceActionResponder.d.ts +49 -0
- package/build/types/ActionRequestResponse/ActionResponder/NiceActionResponder.types.d.ts +7 -0
- package/build/types/ActionRequestResponse/ActionResponder/NiceActionResponderEnvironment.d.ts +42 -0
- package/build/types/ActionSchema/NiceActionSchema.d.ts +101 -0
- package/build/types/ActionSchema/NiceActionSchema.types.d.ts +32 -0
- package/build/types/ActionSchema/action.d.ts +2 -0
- package/build/types/NiceAction/ActionSchema/NiceActionSchema.d.ts +99 -0
- package/build/types/NiceAction/ActionSchema/NiceActionSchema.types.d.ts +31 -0
- package/build/types/NiceAction/ActionSchema/NiceActionSchemaBuilder.d.ts +1 -0
- package/build/types/NiceAction/ActionSchema/action.d.ts +2 -0
- package/build/types/NiceAction/NiceAction.d.ts +64 -0
- package/build/types/NiceAction/NiceAction.types.d.ts +81 -0
- package/build/types/NiceAction/NiceActionPrimed.d.ts +59 -0
- package/build/types/NiceAction/NiceActionPrimed.schema.d.ts +8 -0
- package/build/types/NiceAction/NiceActionResponse.d.ts +32 -0
- package/build/types/errors/err_nice_action.d.ts +62 -0
- package/build/types/index.d.ts +18 -0
- package/build/types/test/nice_action_test_schema.d.ts +30 -0
- package/build/types/utils/isActionResponseJsonObject.d.ts +2 -0
- package/build/types/utils/isPrimedActionJsonObject.d.ts +2 -0
- package/package.json +41 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { NiceActionRequester } from "../ActionRequestResponse/ActionRequester/NiceActionRequester";
|
|
2
|
+
import type { NiceActionDomainResponder } from "../ActionRequestResponse/ActionResponder/NiceActionResponder";
|
|
3
|
+
import { NiceAction } from "../NiceAction/NiceAction";
|
|
4
|
+
import { type INiceAction_JsonObject, type INiceActionPrimed_JsonObject, type TNiceActionResponse_JsonObject } from "../NiceAction/NiceAction.types";
|
|
5
|
+
import { NiceActionPrimed } from "../NiceAction/NiceActionPrimed";
|
|
6
|
+
import { NiceActionResponse } from "../NiceAction/NiceActionResponse";
|
|
7
|
+
import type { INiceActionDomain, INiceActionDomainChildOptions, TActionListener, TInferInputFromSchema, TNiceActionDomainChildDef } from "./NiceActionDomain.types";
|
|
8
|
+
export declare class NiceActionDomain<ACT_DOM extends INiceActionDomain = INiceActionDomain> implements INiceActionDomain<ACT_DOM["allDomains"], ACT_DOM["actions"]> {
|
|
9
|
+
readonly domain: ACT_DOM["domain"];
|
|
10
|
+
readonly allDomains: ACT_DOM["allDomains"];
|
|
11
|
+
readonly actions: ACT_DOM["actions"];
|
|
12
|
+
private _listeners;
|
|
13
|
+
private _requesters;
|
|
14
|
+
private _responders;
|
|
15
|
+
constructor(definition: ACT_DOM);
|
|
16
|
+
createChildDomain<SUB_DOM extends INiceActionDomainChildOptions>(subDomainDef: SUB_DOM & {
|
|
17
|
+
[K in Exclude<keyof SUB_DOM, keyof INiceActionDomainChildOptions>]: never;
|
|
18
|
+
}): NiceActionDomain<TNiceActionDomainChildDef<ACT_DOM, SUB_DOM>>;
|
|
19
|
+
primeUnknown(actionId: ACT_DOM["allDomains"][number], input: unknown): NiceActionPrimed<ACT_DOM, string, ACT_DOM["actions"][string]>;
|
|
20
|
+
primeAction<ID extends keyof ACT_DOM["actions"] & string>(id: ID, input: TInferInputFromSchema<ACT_DOM["actions"][ID]>["Input"]): NiceActionPrimed<ACT_DOM, ID, ACT_DOM["actions"][ID]>;
|
|
21
|
+
action<ID extends keyof ACT_DOM["actions"] & string>(id: ID, hydrationData?: Pick<INiceAction_JsonObject<ACT_DOM, ID>, "cuid" | "timeCreated">): NiceAction<ACT_DOM, ID, ACT_DOM["actions"][ID]>;
|
|
22
|
+
isExactActionDomain<ID extends keyof ACT_DOM["actions"] & string>(action: unknown): action is NiceActionPrimed<ACT_DOM, ID, ACT_DOM["actions"][ID]>;
|
|
23
|
+
matchAction<ID extends keyof ACT_DOM["actions"] & string>(action: unknown, id: ID): NiceActionPrimed<ACT_DOM, ID, ACT_DOM["actions"][ID]> | null;
|
|
24
|
+
/**
|
|
25
|
+
* Add an observer that is called after every action dispatched through this domain.
|
|
26
|
+
* Returns an unsubscribe function — call it to remove the listener.
|
|
27
|
+
*/
|
|
28
|
+
addActionListener(listener: TActionListener): () => void;
|
|
29
|
+
_dispatchAction<P extends NiceActionPrimed<ACT_DOM, string, ACT_DOM["actions"][string]>>(primed: P, envId?: string): Promise<unknown>;
|
|
30
|
+
private _withValidatedInput;
|
|
31
|
+
/**
|
|
32
|
+
* Reconstruct a NiceActionPrimed from its serialized wire format.
|
|
33
|
+
* Runs the schema's deserializeInput if a custom serialization was defined.
|
|
34
|
+
*/
|
|
35
|
+
hydratePrimed<P extends INiceActionPrimed_JsonObject>(serialized: P): NiceActionPrimed<ACT_DOM, keyof ACT_DOM["actions"] & string, ACT_DOM["actions"][P["id"] & keyof ACT_DOM["actions"]]>;
|
|
36
|
+
/**
|
|
37
|
+
* Reconstruct a NiceActionResponse from its serialized wire format.
|
|
38
|
+
* The result is loosely typed — `result.error` is `NiceError<TUnknownNiceErrorDef>`.
|
|
39
|
+
* Use `handleWith` / `forDomain` / `isExact` to route errors on the receiving end.
|
|
40
|
+
*/
|
|
41
|
+
hydrateResponse<R extends TNiceActionResponse_JsonObject>(serialized: R): NiceActionResponse<ACT_DOM, keyof ACT_DOM["actions"] & string, ACT_DOM["actions"][R["id"] & keyof ACT_DOM["actions"]]>;
|
|
42
|
+
/**
|
|
43
|
+
* Register a `NiceActionRequester` on this domain.
|
|
44
|
+
*
|
|
45
|
+
* Pass `options.envId` to register under a named environment — useful when multiple
|
|
46
|
+
* execution environments (e.g. worker, main thread) share the same domain definition.
|
|
47
|
+
* Named requesters are targeted by passing the same `envId` to `action.execute(input, envId)`.
|
|
48
|
+
*
|
|
49
|
+
* Omit `envId` to register the default requester, used when no `envId` is passed to `execute`.
|
|
50
|
+
* Throws `environment_already_registered` / `domain_action_requester_conflict` if already taken.
|
|
51
|
+
*/
|
|
52
|
+
setActionRequester(handler?: NiceActionRequester, options?: {
|
|
53
|
+
envId?: string;
|
|
54
|
+
}): NiceActionRequester;
|
|
55
|
+
/**
|
|
56
|
+
* Register a resolver as the fallback execution path for this domain.
|
|
57
|
+
*
|
|
58
|
+
* When no handler is set (or no envId-matching handler), the domain falls back to the
|
|
59
|
+
* resolver — calling `_resolvePrimed` directly, without re-serializing the input.
|
|
60
|
+
*
|
|
61
|
+
* Pass `options.envId` to register under a named environment.
|
|
62
|
+
* Throws `environment_already_registered` if the envId (or default) is already taken.
|
|
63
|
+
*/
|
|
64
|
+
registerResponder(resolver: NiceActionDomainResponder<ACT_DOM>, options?: {
|
|
65
|
+
envId?: string;
|
|
66
|
+
}): this;
|
|
67
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { NiceActionRequester } from "../ActionRequestResponse/ActionRequester/NiceActionRequester";
|
|
2
|
+
import type { NiceActionSchema } from "../ActionSchema/NiceActionSchema";
|
|
3
|
+
import type { INiceActionErrorDeclaration, TTransportedValue } from "../ActionSchema/NiceActionSchema.types";
|
|
4
|
+
import type { NiceActionPrimed } from "../NiceAction/NiceActionPrimed";
|
|
5
|
+
export type MaybePromise<T> = T | Promise<T>;
|
|
6
|
+
export type TPossibleDomainId = string;
|
|
7
|
+
export type TPossibleDomainIdList = [TPossibleDomainId, ...TPossibleDomainId[]];
|
|
8
|
+
export type TNiceActionDomainSchema = Record<string, NiceActionSchema<TTransportedValue<any, any>, TTransportedValue<any, any>, readonly INiceActionErrorDeclaration<any, any>[]>>;
|
|
9
|
+
/**
|
|
10
|
+
* Data shape for a domain — used for construction and as the type-level schema carrier.
|
|
11
|
+
* Does NOT include class methods.
|
|
12
|
+
*/
|
|
13
|
+
export interface INiceActionDomain<IDS extends TPossibleDomainIdList = TPossibleDomainIdList, SCH extends TNiceActionDomainSchema = TNiceActionDomainSchema> {
|
|
14
|
+
domain: IDS[0];
|
|
15
|
+
allDomains: IDS;
|
|
16
|
+
actions: SCH;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Structural interface implemented by `NiceActionDomainResolver`.
|
|
20
|
+
* Used by `NiceActionDomain` to avoid a circular import with the concrete class.
|
|
21
|
+
*
|
|
22
|
+
* `_resolvePrimed` is the inline dispatch path — calls the registered fn directly
|
|
23
|
+
* without re-serializing/deserializing. Errors from the fn propagate naturally.
|
|
24
|
+
*/
|
|
25
|
+
export interface INiceActionDomainChildOptions<ERR_DOMAIN extends string = string, SCHEMA extends TNiceActionDomainSchema = TNiceActionDomainSchema> {
|
|
26
|
+
domain: ERR_DOMAIN;
|
|
27
|
+
actions: SCHEMA;
|
|
28
|
+
}
|
|
29
|
+
export type TNiceActionDomainChildDef<PARENT_DEF extends INiceActionDomain, SUB extends INiceActionDomainChildOptions> = {
|
|
30
|
+
domain: SUB["domain"];
|
|
31
|
+
allDomains: [SUB["domain"], ...PARENT_DEF["allDomains"]];
|
|
32
|
+
actions: SUB["actions"];
|
|
33
|
+
};
|
|
34
|
+
export type TInferInputFromSchema<SCH> = SCH extends NiceActionSchema<infer IN, any, any> ? {
|
|
35
|
+
Input: IN[0];
|
|
36
|
+
SerdeInput: IN[1];
|
|
37
|
+
} : never;
|
|
38
|
+
export type TInferOutputFromSchema<SCH> = SCH extends NiceActionSchema<any, infer OUT, any> ? {
|
|
39
|
+
Output: OUT[0];
|
|
40
|
+
SerdeOutput: OUT[1];
|
|
41
|
+
} : never;
|
|
42
|
+
/**
|
|
43
|
+
* Handler registered via forDomain.
|
|
44
|
+
*
|
|
45
|
+
* `act.input` is typed as the union of input types for every action in `ACT_DOM`,
|
|
46
|
+
* and `act.coreAction` carries the matching schema — the same narrowing you get
|
|
47
|
+
* from `forActionIds` over all action IDs in the domain.
|
|
48
|
+
*/
|
|
49
|
+
export type TActionHandlerForDomain<ACT_DOM extends INiceActionDomain> = (action: NiceActionPrimed<ACT_DOM, keyof ACT_DOM["actions"] & string, ACT_DOM["actions"][keyof ACT_DOM["actions"] & string]>) => MaybePromise<unknown>;
|
|
50
|
+
/**
|
|
51
|
+
* Handler registered via forActionId — receives a specific action ID, with
|
|
52
|
+
* the primed action's input narrowed to that ID's schema.
|
|
53
|
+
*/
|
|
54
|
+
export type TActionIdHandlerForDomain<ACT_DOM extends INiceActionDomain, ID extends keyof ACT_DOM["actions"] & string> = (action: NiceActionPrimed<ACT_DOM, ID, ACT_DOM["actions"][ID]>) => MaybePromise<unknown>;
|
|
55
|
+
/**
|
|
56
|
+
* Observer called after each action is dispatched.
|
|
57
|
+
* Return value is ignored. Use for logging, metrics, tracing, etc.
|
|
58
|
+
*/
|
|
59
|
+
export type TActionListener = (action: NiceActionPrimed<any, any, any>) => MaybePromise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Broad handler signature used internally for storage and dispatch.
|
|
62
|
+
* Public-facing registration methods use narrower types (`TActionHandlerForDomain`,
|
|
63
|
+
* `TActionIdHandlerForDomain`); they are cast to this for storage.
|
|
64
|
+
*/
|
|
65
|
+
export type TBroadActionRequester<P extends NiceActionPrimed<any, any, any>> = (action: P) => MaybePromise<unknown>;
|
|
66
|
+
/**
|
|
67
|
+
* A single case in a `NiceActionRequester`.
|
|
68
|
+
*
|
|
69
|
+
* Construct via `forDomain` / `forActionId` / `forActionIds` — do not build directly.
|
|
70
|
+
*/
|
|
71
|
+
export interface IActionCase<P extends NiceActionPrimed<any, any, any> = NiceActionPrimed<any, any, any>> {
|
|
72
|
+
readonly _matcher: (action: P) => boolean;
|
|
73
|
+
readonly _requester: TBroadActionRequester<P>;
|
|
74
|
+
}
|
|
75
|
+
export interface IActionHandlerWithId {
|
|
76
|
+
id: string;
|
|
77
|
+
handler: NiceActionRequester;
|
|
78
|
+
}
|
|
79
|
+
export type TDomainActionId<DOM extends INiceActionDomain> = keyof DOM["actions"] & string;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { NiceActionDomain } from "./NiceActionDomain";
|
|
2
|
+
import type { INiceActionDomain } from "./NiceActionDomain.types";
|
|
3
|
+
export declare const createActionDomain: <ACT_DOM extends Omit<INiceActionDomain, "allDomains">>(definition: ACT_DOM) => NiceActionDomain<ACT_DOM & {
|
|
4
|
+
allDomains: [string];
|
|
5
|
+
}>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { NiceActionDomain } from "../../ActionDomain/NiceActionDomain";
|
|
2
|
+
import type { INiceActionDomain, TActionHandlerForDomain, TActionIdHandlerForDomain, TBroadActionRequester } from "../../ActionDomain/NiceActionDomain.types";
|
|
3
|
+
import type { NiceActionPrimed } from "../../NiceAction/NiceActionPrimed";
|
|
4
|
+
export declare class NiceActionRequester {
|
|
5
|
+
private cases;
|
|
6
|
+
private _defaultRequester?;
|
|
7
|
+
handleAction(action: NiceActionPrimed<any, any, any>): Promise<unknown>;
|
|
8
|
+
/**
|
|
9
|
+
* Register a handler that fires for **any** action whose domain matches `domain`.
|
|
10
|
+
* `act.input` is typed as the union of input types for all actions in `domain`.
|
|
11
|
+
* First matching case wins.
|
|
12
|
+
*/
|
|
13
|
+
forDomain<FOR_DOM extends INiceActionDomain>(domain: NiceActionDomain<FOR_DOM>, handler: TActionHandlerForDomain<FOR_DOM>): this;
|
|
14
|
+
/**
|
|
15
|
+
* Register a handler that fires only for the specific action `id`.
|
|
16
|
+
* The handler's `action.input` is narrowed to the schema for that ID.
|
|
17
|
+
* First matching case wins.
|
|
18
|
+
*/
|
|
19
|
+
forActionId<ACT_DOM extends INiceActionDomain, ID extends keyof ACT_DOM["actions"] & string>(domain: NiceActionDomain<ACT_DOM>, id: ID, handler: TActionIdHandlerForDomain<ACT_DOM, ID>): this;
|
|
20
|
+
/**
|
|
21
|
+
* Register a handler that fires for any action whose id is in `ids`.
|
|
22
|
+
* The handler's `action.input` is narrowed to the union of those IDs' schemas.
|
|
23
|
+
* First matching case wins.
|
|
24
|
+
*/
|
|
25
|
+
forActionIds<ACT_DOM extends INiceActionDomain, IDS extends ReadonlyArray<keyof ACT_DOM["actions"] & string>>(domain: NiceActionDomain<ACT_DOM>, ids: IDS, handler: TActionIdHandlerForDomain<ACT_DOM, IDS[number]>): this;
|
|
26
|
+
/**
|
|
27
|
+
* Register a fallback handler that fires when no other case matches.
|
|
28
|
+
* Only one default handler can be registered — calling this twice replaces the previous one.
|
|
29
|
+
*/
|
|
30
|
+
setDefaultHandler(handler: TBroadActionRequester<NiceActionPrimed<any, any, any>>): this;
|
|
31
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { NiceActionDomain } from "../../ActionDomain/NiceActionDomain";
|
|
2
|
+
import type { INiceActionDomain } from "../../ActionDomain/NiceActionDomain.types";
|
|
3
|
+
import type { INiceActionPrimed_JsonObject } from "../../NiceAction/NiceAction.types";
|
|
4
|
+
import type { NiceActionPrimed } from "../../NiceAction/NiceActionPrimed";
|
|
5
|
+
import { NiceActionResponse } from "../../NiceAction/NiceActionResponse";
|
|
6
|
+
import type { TActionResponderFn } from "./NiceActionResponder.types";
|
|
7
|
+
export declare class NiceActionDomainResponder<DOM extends INiceActionDomain> {
|
|
8
|
+
private _domain;
|
|
9
|
+
private _responders;
|
|
10
|
+
constructor(domain: NiceActionDomain<DOM>);
|
|
11
|
+
get domainId(): DOM["domain"];
|
|
12
|
+
/**
|
|
13
|
+
* Register a responder function for a specific action ID in this domain.
|
|
14
|
+
* The input and output types are inferred from the domain's schema for that action ID.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* createDomainResponder(myDomain)
|
|
19
|
+
* .resolve("myAction", async (input) => {
|
|
20
|
+
* return { result: await db.query(input.id) };
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
resolveAction<ID extends keyof DOM["actions"] & string>(actionId: ID, fn: TActionResponderFn<DOM["actions"][ID]>): this;
|
|
25
|
+
/**
|
|
26
|
+
* Internal: called by `NiceActionDomain._dispatchAction` when this resolver is registered
|
|
27
|
+
* as the domain's fallback. Calls the registered fn directly — no re-serialization.
|
|
28
|
+
* Errors from the fn propagate naturally (consistent with handler dispatch).
|
|
29
|
+
*
|
|
30
|
+
* Throws `resolver_action_not_registered` if no fn was registered for the action ID.
|
|
31
|
+
*/
|
|
32
|
+
_resolvePrimed(primed: NiceActionPrimed<any, any, any>): Promise<unknown>;
|
|
33
|
+
/**
|
|
34
|
+
* Internal: hydrate the wire action, call the registered resolver fn, and return a
|
|
35
|
+
* `NiceActionResponse`. Any error thrown by the resolver fn is caught and wrapped in the
|
|
36
|
+
* response as `{ ok: false }` via `castNiceError`.
|
|
37
|
+
*
|
|
38
|
+
* Throws `resolver_action_not_registered` if no fn was registered for the action ID.
|
|
39
|
+
* Throws `hydration_*` errors (from `NiceActionDomain.hydrateAction`) if the action ID
|
|
40
|
+
* is not part of this domain's schema.
|
|
41
|
+
*/
|
|
42
|
+
_dispatch<P extends INiceActionPrimed_JsonObject<DOM, string>>(wire: P): Promise<NiceActionResponse<DOM, P["id"], DOM["actions"][P["id"]]>>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create a `NiceActionDomainResolver` for `domain`.
|
|
46
|
+
* Chain `.resolve(actionId, fn)` calls to register typed resolver functions,
|
|
47
|
+
* then pass the resolver to `createResolverEnvironment`.
|
|
48
|
+
*/
|
|
49
|
+
export declare function createDomainResolver<DOM extends INiceActionDomain>(domain: NiceActionDomain<DOM>): NiceActionDomainResponder<DOM>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { MaybePromise, TInferInputFromSchema, TInferOutputFromSchema } from "../../ActionDomain/NiceActionDomain.types";
|
|
2
|
+
import type { NiceActionSchema } from "../../ActionSchema/NiceActionSchema";
|
|
3
|
+
/**
|
|
4
|
+
* A resolver function for a specific action.
|
|
5
|
+
* Receives the deserialized input and must return (or resolve to) the deserialized output.
|
|
6
|
+
*/
|
|
7
|
+
export type TActionResponderFn<SCH extends NiceActionSchema<any, any, any>> = (input: TInferInputFromSchema<SCH>["Input"]) => MaybePromise<TInferOutputFromSchema<SCH>["Output"]>;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { INiceActionDomain } from "../../ActionDomain/NiceActionDomain.types";
|
|
2
|
+
import type { INiceActionPrimed_JsonObject, TNiceActionResponse_JsonObject } from "../../NiceAction/NiceAction.types";
|
|
3
|
+
import type { NiceActionDomainResponder } from "./NiceActionResponder";
|
|
4
|
+
export declare class NiceActionResponderEnvironment {
|
|
5
|
+
private _resolvers;
|
|
6
|
+
constructor(resolvers: NiceActionDomainResponder<INiceActionDomain>[]);
|
|
7
|
+
/**
|
|
8
|
+
* Dispatch a serialized action to the matching domain resolver.
|
|
9
|
+
*
|
|
10
|
+
* Finds the resolver by `wire.domain`, hydrates the action, calls the registered fn,
|
|
11
|
+
* and returns the serialized response as `ISerializedNiceActionResponse`.
|
|
12
|
+
*
|
|
13
|
+
* Throws `resolver_domain_not_registered` if no resolver was registered for the domain.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* // server handler
|
|
18
|
+
* app.post("/actions", async (req, res) => {
|
|
19
|
+
* const response = await env.dispatch(req.body);
|
|
20
|
+
* res.json(response);
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
dispatch(wire: INiceActionPrimed_JsonObject<INiceActionDomain, string>): Promise<TNiceActionResponse_JsonObject>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Create a `NiceActionResponderEnvironment` from one or more domain resolvers.
|
|
28
|
+
* The environment routes incoming serialized actions to the correct resolver by domain ID.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* const env = createResponderEnvironment([
|
|
33
|
+
* createDomainResolver(paymentDomain)
|
|
34
|
+
* .resolve("chargeCard", async (input) => { ... }),
|
|
35
|
+
* createDomainResolver(authDomain)
|
|
36
|
+
* .resolve("login", async (input) => { ... }),
|
|
37
|
+
* ]);
|
|
38
|
+
*
|
|
39
|
+
* const serializedResponse = await env.dispatch(incomingWire);
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function createResponderEnvironment(resolvers: NiceActionDomainResponder<INiceActionDomain<any, any>>[]): NiceActionResponderEnvironment;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { err_cast_not_nice, type INiceErrorDefinedProps, type InferNiceError, type JSONSerializableValue, type NiceErrorDefined } from "@nice-code/error";
|
|
2
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
3
|
+
import type { INiceActionErrorDeclaration, TInferDeclaredErrors, TNiceActonSchemaInputOptions, TTransportedValue } from "./NiceActionSchema.types";
|
|
4
|
+
export declare class NiceActionSchema<INPUT extends TTransportedValue<any, any> = TTransportedValue<any, any>, OUTPUT extends TTransportedValue<any, any> = TTransportedValue<any>, ERRORS extends readonly INiceActionErrorDeclaration<any, any>[] = readonly []> {
|
|
5
|
+
private _errorDeclarations;
|
|
6
|
+
private inputOptions;
|
|
7
|
+
private outputOptions;
|
|
8
|
+
get inputSchema(): StandardSchemaV1;
|
|
9
|
+
get outputSchema(): StandardSchemaV1;
|
|
10
|
+
/**
|
|
11
|
+
* Declare the input schema (JSON-native or with explicit SERDE type param).
|
|
12
|
+
* For non-JSON-native inputs, prefer the 3-argument form below to avoid
|
|
13
|
+
* needing explicit type parameters.
|
|
14
|
+
*/
|
|
15
|
+
input<VS extends StandardSchemaV1 = StandardSchemaV1, SERDE_IN extends JSONSerializableValue = never>(options: TNiceActonSchemaInputOptions<VS, SERDE_IN>): NiceActionSchema<TTransportedValue<StandardSchemaV1.InferInput<VS>, SERDE_IN>, OUTPUT, ERRORS>;
|
|
16
|
+
/**
|
|
17
|
+
* Declare the input schema with serialization via sequential parameters.
|
|
18
|
+
* TypeScript infers SERDE_IN from `serialize`'s return type (left-to-right),
|
|
19
|
+
* then provides it as the contextual type for `deserialize`'s parameter —
|
|
20
|
+
* no explicit type parameters or casts needed.
|
|
21
|
+
*/
|
|
22
|
+
input<VS extends StandardSchemaV1, SERDE_IN extends JSONSerializableValue>(options: {
|
|
23
|
+
schema: VS;
|
|
24
|
+
}, serialize: (raw: StandardSchemaV1.InferInput<VS>) => SERDE_IN, deserialize: (serde: SERDE_IN) => StandardSchemaV1.InferInput<VS>): NiceActionSchema<TTransportedValue<StandardSchemaV1.InferInput<VS>, SERDE_IN>, OUTPUT, ERRORS>;
|
|
25
|
+
/**
|
|
26
|
+
* Declare the output schema (JSON-native or with explicit SERDE type param).
|
|
27
|
+
* For non-JSON-native outputs, prefer the 3-argument form below to avoid
|
|
28
|
+
* needing explicit type parameters.
|
|
29
|
+
*/
|
|
30
|
+
output<VS extends StandardSchemaV1 = StandardSchemaV1, SERDE_OUT extends JSONSerializableValue = JSONSerializableValue>(options: TNiceActonSchemaInputOptions<VS, SERDE_OUT>): NiceActionSchema<INPUT, TTransportedValue<StandardSchemaV1.InferInput<VS>, SERDE_OUT>, ERRORS>;
|
|
31
|
+
/**
|
|
32
|
+
* Declare the output schema with serialization via sequential parameters.
|
|
33
|
+
* TypeScript infers SERDE_OUT from `serialize`'s return type (left-to-right),
|
|
34
|
+
* then provides it as the contextual type for `deserialize`'s parameter —
|
|
35
|
+
* no explicit type parameters or casts needed.
|
|
36
|
+
*/
|
|
37
|
+
output<VS extends StandardSchemaV1, SERDE_OUT extends JSONSerializableValue>(options: {
|
|
38
|
+
schema: VS;
|
|
39
|
+
}, serialize: (raw: StandardSchemaV1.InferInput<VS>) => SERDE_OUT, deserialize: (serde: SERDE_OUT) => StandardSchemaV1.InferInput<VS>): NiceActionSchema<INPUT, TTransportedValue<StandardSchemaV1.InferInput<VS>, SERDE_OUT>, ERRORS>;
|
|
40
|
+
/**
|
|
41
|
+
* Declare that this action may throw any error from `domain`.
|
|
42
|
+
* `TInferActionError` will include `NiceError<DEF, keyof schema>` in its union.
|
|
43
|
+
*/
|
|
44
|
+
throws<ERR_DEF extends INiceErrorDefinedProps>(domain: NiceErrorDefined<ERR_DEF>): NiceActionSchema<INPUT, OUTPUT, readonly [...ERRORS, INiceActionErrorDeclaration<ERR_DEF, keyof ERR_DEF["schema"] & string>]>;
|
|
45
|
+
/**
|
|
46
|
+
* Declare that this action may throw only the listed `ids` from `domain`.
|
|
47
|
+
* `TInferActionError` will include `NiceError<DEF, IDS[number]>` narrowed to those IDs.
|
|
48
|
+
*/
|
|
49
|
+
throws<ERR_DEF extends INiceErrorDefinedProps, IDS extends ReadonlyArray<keyof ERR_DEF["schema"] & string>>(domain: NiceErrorDefined<ERR_DEF>, ids: IDS): NiceActionSchema<INPUT, OUTPUT, readonly [...ERRORS, INiceActionErrorDeclaration<ERR_DEF, IDS[number] & string>]>;
|
|
50
|
+
/**
|
|
51
|
+
* Serialize raw input to a JSON-serializable form.
|
|
52
|
+
* Uses the schema's serialization.serialize if defined; otherwise the input
|
|
53
|
+
* is already JSON-native and is returned as-is.
|
|
54
|
+
*/
|
|
55
|
+
serializeInput(rawInput: INPUT[0]): JSONSerializableValue;
|
|
56
|
+
/**
|
|
57
|
+
* Deserialize a JSON value back into the raw input type.
|
|
58
|
+
* Uses serialization.deserialize if defined; otherwise the value is cast
|
|
59
|
+
* directly (it's already in the correct shape).
|
|
60
|
+
*/
|
|
61
|
+
deserializeInput(serialized: JSONSerializableValue): INPUT[0];
|
|
62
|
+
/**
|
|
63
|
+
* Validate raw input against the schema defined via `.input({ schema })`.
|
|
64
|
+
* Throws `action_input_validation_failed` if validation fails.
|
|
65
|
+
* Returns the validated (and possibly coerced) value on success.
|
|
66
|
+
* If no input schema was declared, the value is passed through as-is.
|
|
67
|
+
*/
|
|
68
|
+
validateInput(value: unknown, meta: {
|
|
69
|
+
domain: string;
|
|
70
|
+
actionId: string;
|
|
71
|
+
}): Promise<INPUT[0]>;
|
|
72
|
+
/**
|
|
73
|
+
* Serialize raw output to a JSON-serializable form.
|
|
74
|
+
*/
|
|
75
|
+
serializeOutput(rawOutput: OUTPUT[0]): OUTPUT[1];
|
|
76
|
+
/**
|
|
77
|
+
* Deserialize a JSON value back into the raw output type.
|
|
78
|
+
*/
|
|
79
|
+
deserializeOutput(serialized: OUTPUT[1]): OUTPUT[0];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Infers the full error union that a `NiceActionSchema` may throw.
|
|
83
|
+
*
|
|
84
|
+
* Includes every declared `NiceError<DEF, IDS>` from `.throws()` calls, plus
|
|
85
|
+
* `InferNiceError<typeof err_cast_not_nice>` as the always-present fallback
|
|
86
|
+
* for any unrecognized thrown value.
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```ts
|
|
90
|
+
* const payAction = action()
|
|
91
|
+
* .input({ schema: v.object({ amount: v.number() }) })
|
|
92
|
+
* .throws(err_payment)
|
|
93
|
+
* .throws(err_auth, ["unauthenticated"] as const);
|
|
94
|
+
*
|
|
95
|
+
* type PayError = TInferActionError<typeof payAction>;
|
|
96
|
+
* // → NiceError<ErrPaymentDef, keyof ErrPaymentSchema>
|
|
97
|
+
* // | NiceError<ErrAuthDef, "unauthenticated">
|
|
98
|
+
* // | NiceError<ErrCastNotNiceDef, keyof ErrCastNotNiceSchema>
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export type TInferActionError<SCH> = SCH extends NiceActionSchema<any, any, infer DECLS> ? DECLS extends readonly INiceActionErrorDeclaration[] ? TInferDeclaredErrors<DECLS> | InferNiceError<typeof err_cast_not_nice> : InferNiceError<typeof err_cast_not_nice> : never;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type INiceErrorDefinedProps, type JSONSerializableValue, type NiceErrorDefined } from "@nice-code/error";
|
|
2
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
3
|
+
export type TNiceActionJsonSerializableValue = JSONSerializableValue;
|
|
4
|
+
export type TTransportedValue<RAW_VAL = never, SERDE_VAL extends TNiceActionJsonSerializableValue = never> = RAW_VAL extends TNiceActionJsonSerializableValue ? [RAW_VAL] | [RAW_VAL, SERDE_VAL] : [RAW_VAL, SERDE_VAL];
|
|
5
|
+
export type TNiceActionSerializationDefinition<RAW_VAL = any, SERDE_VAL extends TNiceActionJsonSerializableValue = TNiceActionJsonSerializableValue> = {
|
|
6
|
+
serialize: (value: RAW_VAL) => SERDE_VAL;
|
|
7
|
+
deserialize: (value: SERDE_VAL) => RAW_VAL;
|
|
8
|
+
};
|
|
9
|
+
export type TNiceActonSchemaInputOptions<VS extends StandardSchemaV1 = StandardSchemaV1, SERDE_IN extends TNiceActionJsonSerializableValue = TNiceActionJsonSerializableValue> = StandardSchemaV1.InferInput<VS> extends TNiceActionJsonSerializableValue ? {
|
|
10
|
+
schema: VS;
|
|
11
|
+
serialization?: TNiceActionSerializationDefinition<StandardSchemaV1.InferInput<VS>, SERDE_IN>;
|
|
12
|
+
} : {
|
|
13
|
+
schema: VS;
|
|
14
|
+
serialization: TNiceActionSerializationDefinition<StandardSchemaV1.InferInput<VS>, SERDE_IN>;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* One error declaration on an action schema.
|
|
18
|
+
* `IDS` is the subset of error IDs that may be thrown. When the full
|
|
19
|
+
* `keyof schema` union is used it means any ID from the domain can be thrown.
|
|
20
|
+
*
|
|
21
|
+
* Build via `action().throws(domain)` or `action().throws(domain, ids)`.
|
|
22
|
+
*/
|
|
23
|
+
export interface INiceActionErrorDeclaration<ERR_DEF extends INiceErrorDefinedProps = INiceErrorDefinedProps, IDS extends keyof ERR_DEF["schema"] & string = keyof ERR_DEF["schema"] & string> {
|
|
24
|
+
readonly _domain: NiceErrorDefined<ERR_DEF>;
|
|
25
|
+
/** The specific IDs constrained for this declaration, or `undefined` meaning the full domain. */
|
|
26
|
+
readonly _ids: ReadonlyArray<IDS & string> | undefined;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Union of all `NiceError` types that can be thrown from a tuple of error declarations.
|
|
30
|
+
* Distributes over each declaration and unions the results.
|
|
31
|
+
*/
|
|
32
|
+
export type TInferDeclaredErrors<DECLS extends readonly INiceActionErrorDeclaration[]> = TInferErrorFromDeclaration<DECLS[number]>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { err_cast_not_nice, type INiceErrorDefinedProps, type InferNiceError, type JSONSerializableValue, type NiceErrorDefined } from "@nice-code/error";
|
|
2
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
3
|
+
import type { INiceActionErrorDeclaration, TInferDeclaredErrors, TNiceActonSchemaInputOptions, TTransportedValue } from "./NiceActionSchema.types";
|
|
4
|
+
export declare class NiceActionSchema<INPUT extends TTransportedValue<any, any> = TTransportedValue<any, any>, OUTPUT extends TTransportedValue<any, any> = TTransportedValue<any>, ERRORS extends readonly INiceActionErrorDeclaration<any, any>[] = readonly []> {
|
|
5
|
+
private _errorDeclarations;
|
|
6
|
+
private inputOptions;
|
|
7
|
+
private outputOptions;
|
|
8
|
+
/**
|
|
9
|
+
* Declare the input schema (JSON-native or with explicit SERDE type param).
|
|
10
|
+
* For non-JSON-native inputs, prefer the 3-argument form below to avoid
|
|
11
|
+
* needing explicit type parameters.
|
|
12
|
+
*/
|
|
13
|
+
input<VS extends StandardSchemaV1 = StandardSchemaV1, SERDE_IN extends JSONSerializableValue = never>(options: TNiceActonSchemaInputOptions<VS, SERDE_IN>): NiceActionSchema<TTransportedValue<StandardSchemaV1.InferInput<VS>, SERDE_IN>, OUTPUT, ERRORS>;
|
|
14
|
+
/**
|
|
15
|
+
* Declare the input schema with serialization via sequential parameters.
|
|
16
|
+
* TypeScript infers SERDE_IN from `serialize`'s return type (left-to-right),
|
|
17
|
+
* then provides it as the contextual type for `deserialize`'s parameter —
|
|
18
|
+
* no explicit type parameters or casts needed.
|
|
19
|
+
*/
|
|
20
|
+
input<VS extends StandardSchemaV1, SERDE_IN extends JSONSerializableValue>(options: {
|
|
21
|
+
schema: VS;
|
|
22
|
+
}, serialize: (raw: StandardSchemaV1.InferInput<VS>) => SERDE_IN, deserialize: (serde: SERDE_IN) => StandardSchemaV1.InferInput<VS>): NiceActionSchema<TTransportedValue<StandardSchemaV1.InferInput<VS>, SERDE_IN>, OUTPUT, ERRORS>;
|
|
23
|
+
/**
|
|
24
|
+
* Declare the output schema (JSON-native or with explicit SERDE type param).
|
|
25
|
+
* For non-JSON-native outputs, prefer the 3-argument form below to avoid
|
|
26
|
+
* needing explicit type parameters.
|
|
27
|
+
*/
|
|
28
|
+
output<VS extends StandardSchemaV1 = StandardSchemaV1, SERDE_OUT extends JSONSerializableValue = JSONSerializableValue>(options: TNiceActonSchemaInputOptions<VS, SERDE_OUT>): NiceActionSchema<INPUT, TTransportedValue<StandardSchemaV1.InferInput<VS>, SERDE_OUT>, ERRORS>;
|
|
29
|
+
/**
|
|
30
|
+
* Declare the output schema with serialization via sequential parameters.
|
|
31
|
+
* TypeScript infers SERDE_OUT from `serialize`'s return type (left-to-right),
|
|
32
|
+
* then provides it as the contextual type for `deserialize`'s parameter —
|
|
33
|
+
* no explicit type parameters or casts needed.
|
|
34
|
+
*/
|
|
35
|
+
output<VS extends StandardSchemaV1, SERDE_OUT extends JSONSerializableValue>(options: {
|
|
36
|
+
schema: VS;
|
|
37
|
+
}, serialize: (raw: StandardSchemaV1.InferInput<VS>) => SERDE_OUT, deserialize: (serde: SERDE_OUT) => StandardSchemaV1.InferInput<VS>): NiceActionSchema<INPUT, TTransportedValue<StandardSchemaV1.InferInput<VS>, SERDE_OUT>, ERRORS>;
|
|
38
|
+
/**
|
|
39
|
+
* Declare that this action may throw any error from `domain`.
|
|
40
|
+
* `TInferActionError` will include `NiceError<DEF, keyof schema>` in its union.
|
|
41
|
+
*/
|
|
42
|
+
throws<ERR_DEF extends INiceErrorDefinedProps>(domain: NiceErrorDefined<ERR_DEF>): NiceActionSchema<INPUT, OUTPUT, readonly [...ERRORS, INiceActionErrorDeclaration<ERR_DEF, keyof ERR_DEF["schema"] & string>]>;
|
|
43
|
+
/**
|
|
44
|
+
* Declare that this action may throw only the listed `ids` from `domain`.
|
|
45
|
+
* `TInferActionError` will include `NiceError<DEF, IDS[number]>` narrowed to those IDs.
|
|
46
|
+
*/
|
|
47
|
+
throws<ERR_DEF extends INiceErrorDefinedProps, IDS extends ReadonlyArray<keyof ERR_DEF["schema"] & string>>(domain: NiceErrorDefined<ERR_DEF>, ids: IDS): NiceActionSchema<INPUT, OUTPUT, readonly [...ERRORS, INiceActionErrorDeclaration<ERR_DEF, IDS[number] & string>]>;
|
|
48
|
+
/**
|
|
49
|
+
* Serialize raw input to a JSON-serializable form.
|
|
50
|
+
* Uses the schema's serialization.serialize if defined; otherwise the input
|
|
51
|
+
* is already JSON-native and is returned as-is.
|
|
52
|
+
*/
|
|
53
|
+
serializeInput(rawInput: INPUT[0]): JSONSerializableValue;
|
|
54
|
+
/**
|
|
55
|
+
* Deserialize a JSON value back into the raw input type.
|
|
56
|
+
* Uses serialization.deserialize if defined; otherwise the value is cast
|
|
57
|
+
* directly (it's already in the correct shape).
|
|
58
|
+
*/
|
|
59
|
+
deserializeInput(serialized: JSONSerializableValue): INPUT[0];
|
|
60
|
+
/**
|
|
61
|
+
* Validate raw input against the schema defined via `.input({ schema })`.
|
|
62
|
+
* Throws `action_input_validation_failed` if validation fails.
|
|
63
|
+
* Returns the validated (and possibly coerced) value on success.
|
|
64
|
+
* If no input schema was declared, the value is passed through as-is.
|
|
65
|
+
*/
|
|
66
|
+
validateInput(value: unknown, meta: {
|
|
67
|
+
domain: string;
|
|
68
|
+
actionId: string;
|
|
69
|
+
}): Promise<INPUT[0]>;
|
|
70
|
+
/**
|
|
71
|
+
* Serialize raw output to a JSON-serializable form.
|
|
72
|
+
*/
|
|
73
|
+
serializeOutput(rawOutput: OUTPUT[0]): OUTPUT[1];
|
|
74
|
+
/**
|
|
75
|
+
* Deserialize a JSON value back into the raw output type.
|
|
76
|
+
*/
|
|
77
|
+
deserializeOutput(serialized: OUTPUT[1]): OUTPUT[0];
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Infers the full error union that a `NiceActionSchema` may throw.
|
|
81
|
+
*
|
|
82
|
+
* Includes every declared `NiceError<DEF, IDS>` from `.throws()` calls, plus
|
|
83
|
+
* `InferNiceError<typeof err_cast_not_nice>` as the always-present fallback
|
|
84
|
+
* for any unrecognized thrown value.
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* const payAction = action()
|
|
89
|
+
* .input({ schema: v.object({ amount: v.number() }) })
|
|
90
|
+
* .throws(err_payment)
|
|
91
|
+
* .throws(err_auth, ["unauthenticated"] as const);
|
|
92
|
+
*
|
|
93
|
+
* type PayError = TInferActionError<typeof payAction>;
|
|
94
|
+
* // → NiceError<ErrPaymentDef, keyof ErrPaymentSchema>
|
|
95
|
+
* // | NiceError<ErrAuthDef, "unauthenticated">
|
|
96
|
+
* // | NiceError<ErrCastNotNiceDef, keyof ErrCastNotNiceSchema>
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
export type TInferActionError<SCH> = SCH extends NiceActionSchema<any, any, infer DECLS> ? DECLS extends readonly INiceActionErrorDeclaration[] ? TInferDeclaredErrors<DECLS> | InferNiceError<typeof err_cast_not_nice> : InferNiceError<typeof err_cast_not_nice> : never;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type INiceErrorDefinedProps, type JSONSerializableValue, type NiceErrorDefined } from "@nice-code/error";
|
|
2
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
3
|
+
export type TTransportedValue<RAW_VAL = never, SERDE_VAL extends JSONSerializableValue = never> = RAW_VAL extends JSONSerializableValue ? [RAW_VAL] | [RAW_VAL, SERDE_VAL] : [RAW_VAL, SERDE_VAL];
|
|
4
|
+
export type TNiceActionSerializationDefinition<RAW_VAL = any, SERDE_VAL extends JSONSerializableValue = JSONSerializableValue> = {
|
|
5
|
+
serialize: (value: RAW_VAL) => SERDE_VAL;
|
|
6
|
+
deserialize: (value: SERDE_VAL) => RAW_VAL;
|
|
7
|
+
};
|
|
8
|
+
export type TNiceActonSchemaInputOptions<VS extends StandardSchemaV1 = StandardSchemaV1, SERDE_IN extends JSONSerializableValue = JSONSerializableValue> = StandardSchemaV1.InferInput<VS> extends JSONSerializableValue ? {
|
|
9
|
+
schema: VS;
|
|
10
|
+
serialization?: TNiceActionSerializationDefinition<StandardSchemaV1.InferInput<VS>, SERDE_IN>;
|
|
11
|
+
} : {
|
|
12
|
+
schema: VS;
|
|
13
|
+
serialization: TNiceActionSerializationDefinition<StandardSchemaV1.InferInput<VS>, SERDE_IN>;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* One error declaration on an action schema.
|
|
17
|
+
* `IDS` is the subset of error IDs that may be thrown. When the full
|
|
18
|
+
* `keyof schema` union is used it means any ID from the domain can be thrown.
|
|
19
|
+
*
|
|
20
|
+
* Build via `action().throws(domain)` or `action().throws(domain, ids)`.
|
|
21
|
+
*/
|
|
22
|
+
export interface INiceActionErrorDeclaration<ERR_DEF extends INiceErrorDefinedProps = INiceErrorDefinedProps, IDS extends keyof ERR_DEF["schema"] & string = keyof ERR_DEF["schema"] & string> {
|
|
23
|
+
readonly _domain: NiceErrorDefined<ERR_DEF>;
|
|
24
|
+
/** The specific IDs constrained for this declaration, or `undefined` meaning the full domain. */
|
|
25
|
+
readonly _ids: ReadonlyArray<IDS & string> | undefined;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Union of all `NiceError` types that can be thrown from a tuple of error declarations.
|
|
29
|
+
* Distributes over each declaration and unions the results.
|
|
30
|
+
*/
|
|
31
|
+
export type TInferDeclaredErrors<DECLS extends readonly INiceActionErrorDeclaration[]> = TInferErrorFromDeclaration<DECLS[number]>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
|
+
import type { NiceActionDomain } from "../ActionDomain/NiceActionDomain";
|
|
3
|
+
import type { INiceActionDomain, TInferInputFromSchema, TInferOutputFromSchema } from "../ActionDomain/NiceActionDomain.types";
|
|
4
|
+
import type { TInferActionError } from "../ActionSchema/NiceActionSchema";
|
|
5
|
+
import { EActionState, type INiceAction, type INiceAction_JsonObject, type INiceActionPrimed_JsonObject, type NiceActionResult } from "./NiceAction.types";
|
|
6
|
+
import { NiceActionPrimed } from "./NiceActionPrimed";
|
|
7
|
+
import { NiceActionResponse } from "./NiceActionResponse";
|
|
8
|
+
export declare class NiceAction<DOM extends INiceActionDomain, ID extends keyof DOM["actions"] & string, SCH extends DOM["actions"][ID]> implements INiceAction<DOM, ID> {
|
|
9
|
+
readonly actionDomain: NiceActionDomain<DOM>;
|
|
10
|
+
readonly schema: SCH;
|
|
11
|
+
readonly id: ID;
|
|
12
|
+
readonly type = EActionState.empty;
|
|
13
|
+
readonly domain: DOM["domain"];
|
|
14
|
+
readonly allDomains: DOM["allDomains"];
|
|
15
|
+
readonly _actionDomain: NiceActionDomain<DOM>;
|
|
16
|
+
readonly timeCreated: number;
|
|
17
|
+
readonly cuid: string;
|
|
18
|
+
constructor(actionDomain: NiceActionDomain<DOM>, schema: SCH, id: ID, hydrationData?: Pick<INiceAction_JsonObject<DOM, ID>, "cuid" | "timeCreated">);
|
|
19
|
+
/**
|
|
20
|
+
* Serialize this action definition (without input) to a JSON-safe object.
|
|
21
|
+
* Useful for describing which action will be invoked without yet having input.
|
|
22
|
+
*/
|
|
23
|
+
toJsonObject(): INiceAction_JsonObject<DOM, ID>;
|
|
24
|
+
toValidationSchema(): StandardSchemaV1;
|
|
25
|
+
is(action: unknown): action is NiceActionPrimed<DOM, ID, SCH>;
|
|
26
|
+
prime(input: TInferInputFromSchema<SCH>["Input"], hydrationData?: Pick<INiceActionPrimed_JsonObject<DOM, ID>, "timePrimed">): NiceActionPrimed<DOM, ID, SCH>;
|
|
27
|
+
/**
|
|
28
|
+
* Prime this action with input and immediately execute it through the domain handler or resolver.
|
|
29
|
+
*
|
|
30
|
+
* Pass `envId` to target a specific named handler/resolver registered on the domain via
|
|
31
|
+
* `setActionHandler(h, { envId })` or `registerResolver(r, { envId })`.
|
|
32
|
+
* Throws `action_environment_not_found` if no handler or resolver with that id exists.
|
|
33
|
+
*/
|
|
34
|
+
execute(input: TInferInputFromSchema<SCH>["Input"], envId?: string): Promise<TInferOutputFromSchema<SCH>["Output"]>;
|
|
35
|
+
/**
|
|
36
|
+
* Like `execute`, but catches thrown errors and returns a `NiceActionResult` discriminated union
|
|
37
|
+
* instead of propagating. On success: `{ ok: true, value }`. On failure: `{ ok: false, error }`.
|
|
38
|
+
*
|
|
39
|
+
* The `error` type is the union of all `NiceError` types declared via `.throws()` on the schema,
|
|
40
|
+
* plus `InferNiceError<typeof err_cast_not_nice>` as the always-present fallback.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* const result = await domain.action("getUser").executeSafe({ userId: "123" });
|
|
45
|
+
* if (!result.ok) {
|
|
46
|
+
* result.error.handleWith([
|
|
47
|
+
* forDomain(err_auth, (h) => res.status(401).end()),
|
|
48
|
+
* ]);
|
|
49
|
+
* return;
|
|
50
|
+
* }
|
|
51
|
+
* console.log(result.value);
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
executeSafe(input: TInferInputFromSchema<SCH>["Input"], envId?: string): Promise<NiceActionResult<TInferOutputFromSchema<SCH>["Output"], TInferActionError<SCH>>>;
|
|
55
|
+
/**
|
|
56
|
+
* Prime this action with input, execute it, and return a `NiceActionResponse`
|
|
57
|
+
* that carries both the original primed action (domain + actionId + input) and
|
|
58
|
+
* the result (`{ ok: true, value }` or `{ ok: false, error }`).
|
|
59
|
+
*
|
|
60
|
+
* The response can be serialized for cross-boundary transport via `toJsonObject()`.
|
|
61
|
+
* Reconstruct on the receiving end with `domain.hydrateResponse(wire)`.
|
|
62
|
+
*/
|
|
63
|
+
executeToResponse(input: TInferInputFromSchema<SCH>["Input"], envId?: string): Promise<NiceActionResponse<DOM, ID, SCH>>;
|
|
64
|
+
}
|