UNPKG

next-safe-action

Version:

Type safe and validated Server Actions in your Next.js project.

931 lines (916 loc) 30.1 kB
// ../../node_modules/.pnpm/deepmerge-ts@7.1.5/node_modules/deepmerge-ts/dist/index.mjs var actions = { defaultMerge: Symbol("deepmerge-ts: default merge"), skip: Symbol("deepmerge-ts: skip"), }; var actionsInto = { defaultMerge: actions.defaultMerge, }; function defaultMetaDataUpdater(previousMeta, metaMeta) { return metaMeta; } function defaultFilterValues(values, meta) { return values.filter((value) => value !== void 0); } var ObjectType; (function (ObjectType2) { ObjectType2[(ObjectType2["NOT"] = 0)] = "NOT"; ObjectType2[(ObjectType2["RECORD"] = 1)] = "RECORD"; ObjectType2[(ObjectType2["ARRAY"] = 2)] = "ARRAY"; ObjectType2[(ObjectType2["SET"] = 3)] = "SET"; ObjectType2[(ObjectType2["MAP"] = 4)] = "MAP"; ObjectType2[(ObjectType2["OTHER"] = 5)] = "OTHER"; })(ObjectType || (ObjectType = {})); function getObjectType(object) { if (typeof object !== "object" || object === null) { return 0; } if (Array.isArray(object)) { return 2; } if (isRecord(object)) { return 1; } if (object instanceof Set) { return 3; } if (object instanceof Map) { return 4; } return 5; } function getKeys(objects) { const keys = /* @__PURE__ */ new Set(); for (const object of objects) { for (const key of [...Object.keys(object), ...Object.getOwnPropertySymbols(object)]) { keys.add(key); } } return keys; } function objectHasProperty(object, property) { return typeof object === "object" && Object.prototype.propertyIsEnumerable.call(object, property); } function getIterableOfIterables(iterables) { let mut_iterablesIndex = 0; let mut_iterator = iterables[0]?.[Symbol.iterator](); return { [Symbol.iterator]() { return { next() { do { if (mut_iterator === void 0) { return { done: true, value: void 0 }; } const result = mut_iterator.next(); if (result.done === true) { mut_iterablesIndex += 1; mut_iterator = iterables[mut_iterablesIndex]?.[Symbol.iterator](); continue; } return { done: false, value: result.value, }; } while (true); }, }; }, }; } var validRecordToStringValues = ["[object Object]", "[object Module]"]; function isRecord(value) { if (!validRecordToStringValues.includes(Object.prototype.toString.call(value))) { return false; } const { constructor } = value; if (constructor === void 0) { return true; } const prototype = constructor.prototype; if ( prototype === null || typeof prototype !== "object" || !validRecordToStringValues.includes(Object.prototype.toString.call(prototype)) ) { return false; } if (!prototype.hasOwnProperty("isPrototypeOf")) { return false; } return true; } function mergeRecords$1(values, utils, meta) { const result = {}; for (const key of getKeys(values)) { const propValues = []; for (const value of values) { if (objectHasProperty(value, key)) { propValues.push(value[key]); } } if (propValues.length === 0) { continue; } const updatedMeta = utils.metaDataUpdater(meta, { key, parents: values, }); const propertyResult = mergeUnknowns(propValues, utils, updatedMeta); if (propertyResult === actions.skip) { continue; } if (key === "__proto__") { Object.defineProperty(result, key, { value: propertyResult, configurable: true, enumerable: true, writable: true, }); } else { result[key] = propertyResult; } } return result; } function mergeArrays$1(values) { return values.flat(); } function mergeSets$1(values) { return new Set(getIterableOfIterables(values)); } function mergeMaps$1(values) { return new Map(getIterableOfIterables(values)); } function mergeOthers$1(values) { return values.at(-1); } var mergeFunctions = { mergeRecords: mergeRecords$1, mergeArrays: mergeArrays$1, mergeSets: mergeSets$1, mergeMaps: mergeMaps$1, mergeOthers: mergeOthers$1, }; function deepmerge(...objects) { return deepmergeCustom({})(...objects); } function deepmergeCustom(options, rootMetaData) { const utils = getUtils(options, customizedDeepmerge); function customizedDeepmerge(...objects) { return mergeUnknowns(objects, utils, rootMetaData); } return customizedDeepmerge; } function getUtils(options, customizedDeepmerge) { return { defaultMergeFunctions: mergeFunctions, mergeFunctions: { ...mergeFunctions, ...Object.fromEntries( Object.entries(options) .filter(([key, option]) => Object.hasOwn(mergeFunctions, key)) .map(([key, option]) => (option === false ? [key, mergeFunctions.mergeOthers] : [key, option])) ), }, metaDataUpdater: options.metaDataUpdater ?? defaultMetaDataUpdater, deepmerge: customizedDeepmerge, useImplicitDefaultMerging: options.enableImplicitDefaultMerging ?? false, filterValues: options.filterValues === false ? void 0 : (options.filterValues ?? defaultFilterValues), actions, }; } function mergeUnknowns(values, utils, meta) { const filteredValues = utils.filterValues?.(values, meta) ?? values; if (filteredValues.length === 0) { return void 0; } if (filteredValues.length === 1) { return mergeOthers(filteredValues, utils, meta); } const type = getObjectType(filteredValues[0]); if (type !== 0 && type !== 5) { for (let mut_index = 1; mut_index < filteredValues.length; mut_index++) { if (getObjectType(filteredValues[mut_index]) === type) { continue; } return mergeOthers(filteredValues, utils, meta); } } switch (type) { case 1: { return mergeRecords(filteredValues, utils, meta); } case 2: { return mergeArrays(filteredValues, utils, meta); } case 3: { return mergeSets(filteredValues, utils, meta); } case 4: { return mergeMaps(filteredValues, utils, meta); } default: { return mergeOthers(filteredValues, utils, meta); } } } function mergeRecords(values, utils, meta) { const result = utils.mergeFunctions.mergeRecords(values, utils, meta); if ( result === actions.defaultMerge || (utils.useImplicitDefaultMerging && result === void 0 && utils.mergeFunctions.mergeRecords !== utils.defaultMergeFunctions.mergeRecords) ) { return utils.defaultMergeFunctions.mergeRecords(values, utils, meta); } return result; } function mergeArrays(values, utils, meta) { const result = utils.mergeFunctions.mergeArrays(values, utils, meta); if ( result === actions.defaultMerge || (utils.useImplicitDefaultMerging && result === void 0 && utils.mergeFunctions.mergeArrays !== utils.defaultMergeFunctions.mergeArrays) ) { return utils.defaultMergeFunctions.mergeArrays(values); } return result; } function mergeSets(values, utils, meta) { const result = utils.mergeFunctions.mergeSets(values, utils, meta); if ( result === actions.defaultMerge || (utils.useImplicitDefaultMerging && result === void 0 && utils.mergeFunctions.mergeSets !== utils.defaultMergeFunctions.mergeSets) ) { return utils.defaultMergeFunctions.mergeSets(values); } return result; } function mergeMaps(values, utils, meta) { const result = utils.mergeFunctions.mergeMaps(values, utils, meta); if ( result === actions.defaultMerge || (utils.useImplicitDefaultMerging && result === void 0 && utils.mergeFunctions.mergeMaps !== utils.defaultMergeFunctions.mergeMaps) ) { return utils.defaultMergeFunctions.mergeMaps(values); } return result; } function mergeOthers(values, utils, meta) { const result = utils.mergeFunctions.mergeOthers(values, utils, meta); if ( result === actions.defaultMerge || (utils.useImplicitDefaultMerging && result === void 0 && utils.mergeFunctions.mergeOthers !== utils.defaultMergeFunctions.mergeOthers) ) { return utils.defaultMergeFunctions.mergeOthers(values); } return result; } // src/next/errors/bailout-to-csr.ts var BAILOUT_TO_CSR = "BAILOUT_TO_CLIENT_SIDE_RENDERING"; function isBailoutToCSRError(err) { if (typeof err !== "object" || err === null || !("digest" in err)) { return false; } return err.digest === BAILOUT_TO_CSR; } // src/next/errors/http-access-fallback.ts var HTTPAccessErrorStatus = { NOT_FOUND: 404, FORBIDDEN: 403, UNAUTHORIZED: 401, }; var ALLOWED_CODES = new Set(Object.values(HTTPAccessErrorStatus)); var HTTP_ERROR_FALLBACK_ERROR_CODE = "NEXT_HTTP_ERROR_FALLBACK"; function isHTTPAccessFallbackError(error) { if (typeof error !== "object" || error === null || !("digest" in error) || typeof error.digest !== "string") { return false; } const [prefix, httpStatus] = error.digest.split(";"); return prefix === HTTP_ERROR_FALLBACK_ERROR_CODE && ALLOWED_CODES.has(Number(httpStatus)); } function getAccessFallbackHTTPStatus(error) { const httpStatus = error.digest.split(";")[1]; return Number(httpStatus); } // src/next/errors/redirect.ts var RedirectStatusCode = /* @__PURE__ */ ((RedirectStatusCode2) => { RedirectStatusCode2[(RedirectStatusCode2["SeeOther"] = 303)] = "SeeOther"; RedirectStatusCode2[(RedirectStatusCode2["TemporaryRedirect"] = 307)] = "TemporaryRedirect"; RedirectStatusCode2[(RedirectStatusCode2["PermanentRedirect"] = 308)] = "PermanentRedirect"; return RedirectStatusCode2; })(RedirectStatusCode || {}); var REDIRECT_ERROR_CODE = "NEXT_REDIRECT"; function isRedirectError(error) { if (typeof error !== "object" || error === null || !("digest" in error) || typeof error.digest !== "string") { return false; } const digest = error.digest.split(";"); const [errorCode, type] = digest; const destination = digest.slice(2, -2).join(";"); const status = digest.at(-2); const statusCode = Number(status); return ( errorCode === REDIRECT_ERROR_CODE && (type === "replace" || type === "push") && typeof destination === "string" && !isNaN(statusCode) && statusCode in RedirectStatusCode ); } // src/next/errors/router.ts function isNextRouterError(error) { return isRedirectError(error) || isHTTPAccessFallbackError(error); } // src/next/errors/dynamic-usage.ts var DYNAMIC_ERROR_CODE = "DYNAMIC_SERVER_USAGE"; function isDynamicServerError(err) { if (typeof err !== "object" || err === null || !("digest" in err) || typeof err.digest !== "string") { return false; } return err.digest === DYNAMIC_ERROR_CODE; } function isDynamicPostponeReason(reason) { return ( reason.includes("needs to bail out of prerendering at this point because it used") && reason.includes("Learn more: https://nextjs.org/docs/messages/ppr-caught-error") ); } function isDynamicPostpone(err) { if ( typeof err === "object" && err !== null && // eslint-disable-next-line typeof err.message === "string" ) { return isDynamicPostponeReason(err.message); } return false; } var isDynamicUsageError = (err) => isDynamicServerError(err) || isBailoutToCSRError(err) || isNextRouterError(err) || isDynamicPostpone(err); // src/next/errors/postpone.ts var REACT_POSTPONE_TYPE = Symbol.for("react.postpone"); function isPostpone(error) { return ( typeof error === "object" && error !== null && // eslint-disable-next-line error.$$typeof === REACT_POSTPONE_TYPE ); } // src/next/errors/index.ts var FrameworkErrorHandler = class _FrameworkErrorHandler { #frameworkError; static isNavigationError(error) { return isNextRouterError(error) || isBailoutToCSRError(error) || isDynamicUsageError(error) || isPostpone(error); } static getNavigationKind(error) { if (isRedirectError(error)) { return "redirect"; } else if (isHTTPAccessFallbackError(error) && getAccessFallbackHTTPStatus(error) === 404) { return "notFound"; } else if (isHTTPAccessFallbackError(error) && getAccessFallbackHTTPStatus(error) === 403) { return "forbidden"; } else if (isHTTPAccessFallbackError(error) && getAccessFallbackHTTPStatus(error) === 401) { return "unauthorized"; } else { return "other"; } } // Used in action builder. handleError(e) { if (_FrameworkErrorHandler.isNavigationError(e)) { this.#frameworkError = e; return; } throw e; } get error() { return this.#frameworkError; } }; // src/standard-schema.ts async function standardParse(schema, value) { return schema["~standard"].validate(value); } // src/utils.ts var DEFAULT_SERVER_ERROR_MESSAGE = "Something went wrong while executing the operation."; var isError = (error) => error instanceof Error; var winningBoolean = (...args) => { return args.reduce((acc, v) => (typeof v === "boolean" ? v : acc), false); }; // src/validation-errors.ts var getKey = (segment) => (typeof segment === "object" ? segment.key : segment); var getIssueMessage = (issue) => { if (issue.unionErrors) { return issue.unionErrors.map((u) => u.issues.map((i) => i.message)).flat(); } return issue.message; }; var buildValidationErrors = (issues) => { const ve = {}; for (const issue of issues) { const { path, message, unionErrors } = issue; if (!path || path.length === 0) { ve._errors = ve._errors ? [...ve._errors, message] : [message]; continue; } let ref = ve; for (let i = 0; i < path.length - 1; i++) { const k = getKey(path[i]); if (!ref[k]) { ref[k] = {}; } ref = ref[k]; } const key = getKey(path[path.length - 1]); const issueMessage = getIssueMessage(issue); ref[key] = ref[key]?._errors ? { ...structuredClone(ref[key]), _errors: [...ref[key]._errors, issueMessage], } : { ...structuredClone(ref[key]), _errors: unionErrors ? issueMessage : [issueMessage] }; } return ve; }; var ActionServerValidationError = class extends Error { validationErrors; constructor(validationErrors) { super("Server Action server validation error(s) occurred"); this.validationErrors = validationErrors; } }; var ActionValidationError = class extends Error { validationErrors; constructor(validationErrors, overriddenErrorMessage) { super(overriddenErrorMessage ?? "Server Action validation error(s) occurred"); this.validationErrors = validationErrors; } }; var ActionBindArgsValidationError = class extends Error { validationErrors; constructor(validationErrors) { super("Server Action bind args validation error(s) occurred"); this.validationErrors = validationErrors; } }; function returnValidationErrors(schema, validationErrors) { throw new ActionServerValidationError(validationErrors); } function formatValidationErrors(validationErrors) { return validationErrors; } function flattenValidationErrors(validationErrors) { const flattened = { formErrors: [], fieldErrors: {}, }; for (const [key, value] of Object.entries(validationErrors ?? {})) { if (key === "_errors" && Array.isArray(value)) { flattened.formErrors = [...value]; } else { if ("_errors" in value) { flattened.fieldErrors[key] = [...value._errors]; } } } return flattened; } var ActionMetadataValidationError = class extends Error { validationErrors; constructor(validationErrors) { super("Invalid metadata input. Please be sure to pass metadata via `metadata` method before defining the action."); this.name = "ActionMetadataError"; this.validationErrors = validationErrors; } }; var ActionOutputDataValidationError = class extends Error { validationErrors; constructor(validationErrors) { super( "Invalid action data (output). Please be sure to return data following the shape of the schema passed to `dataSchema` method." ); this.name = "ActionOutputDataError"; this.validationErrors = validationErrors; } }; // src/action-builder.ts function actionBuilder(args) { const bindArgsSchemas = args.bindArgsSchemas ?? []; function buildAction({ withState }) { return { action: (serverCodeFn, utils) => { return async (...clientInputs) => { let currentCtx = {}; const middlewareResult = { success: false }; let prevResult = {}; const parsedInputDatas = []; const frameworkErrorHandler = new FrameworkErrorHandler(); if (withState) { prevResult = clientInputs.splice(bindArgsSchemas.length, 1)[0]; } if (bindArgsSchemas.length + 1 > clientInputs.length) { clientInputs.push(void 0); } const executeMiddlewareStack = async (idx = 0) => { if (frameworkErrorHandler.error) { return; } const middlewareFn = args.middlewareFns[idx]; middlewareResult.ctx = currentCtx; try { if (idx === 0) { if (args.metadataSchema) { const parsedMd = await standardParse(args.metadataSchema, args.metadata); if (parsedMd.issues) { throw new ActionMetadataValidationError(buildValidationErrors(parsedMd.issues)); } } } if (middlewareFn) { await middlewareFn({ clientInput: clientInputs.at(-1), // pass raw client input bindArgsClientInputs: bindArgsSchemas.length ? clientInputs.slice(0, -1) : [], ctx: currentCtx, metadata: args.metadata, next: async (nextOpts) => { currentCtx = deepmerge(currentCtx, nextOpts?.ctx ?? {}); await executeMiddlewareStack(idx + 1); return middlewareResult; }, }).catch((e) => { frameworkErrorHandler.handleError(e); if (frameworkErrorHandler.error) { middlewareResult.success = false; middlewareResult.navigationKind = FrameworkErrorHandler.getNavigationKind( frameworkErrorHandler.error ); } }); } else { const parsedInputs = await Promise.all( clientInputs.map(async (input, i) => { if (i === clientInputs.length - 1) { if (typeof args.inputSchemaFn === "undefined") { return { value: void 0, }; } return standardParse(await args.inputSchemaFn(), input); } return standardParse(bindArgsSchemas[i], input); }) ); let hasBindValidationErrors = false; const bindArgsValidationErrors = Array(parsedInputs.length - 1).fill({}); for (let i = 0; i < parsedInputs.length; i++) { const parsedInput = parsedInputs[i]; if (!parsedInput.issues) { parsedInputDatas.push(parsedInput.value); } else { if (i < parsedInputs.length - 1) { bindArgsValidationErrors[i] = buildValidationErrors(parsedInput.issues); hasBindValidationErrors = true; } else { const validationErrors = buildValidationErrors(parsedInput.issues); middlewareResult.validationErrors = await Promise.resolve( args.handleValidationErrorsShape(validationErrors, { clientInput: clientInputs.at(-1), bindArgsClientInputs: bindArgsSchemas.length ? clientInputs.slice(0, -1) : [], ctx: currentCtx, metadata: args.metadata, }) ); } } } if (hasBindValidationErrors) { throw new ActionBindArgsValidationError(bindArgsValidationErrors); } if (middlewareResult.validationErrors) { return; } const scfArgs = []; scfArgs[0] = { parsedInput: parsedInputDatas.at(-1), bindArgsParsedInputs: parsedInputDatas.slice(0, -1), clientInput: clientInputs.at(-1), bindArgsClientInputs: bindArgsSchemas.length ? clientInputs.slice(0, -1) : [], ctx: currentCtx, metadata: args.metadata, }; if (withState) { scfArgs[1] = { prevResult: structuredClone(prevResult) }; } const data = await serverCodeFn(...scfArgs).catch((e) => frameworkErrorHandler.handleError(e)); if (typeof args.outputSchema !== "undefined" && !frameworkErrorHandler.error) { const parsedData = await standardParse(args.outputSchema, data); if (parsedData.issues) { throw new ActionOutputDataValidationError(buildValidationErrors(parsedData.issues)); } } if (frameworkErrorHandler.error) { middlewareResult.success = false; middlewareResult.navigationKind = FrameworkErrorHandler.getNavigationKind( frameworkErrorHandler.error ); } else { middlewareResult.success = true; middlewareResult.data = data; } middlewareResult.parsedInput = parsedInputDatas.at(-1); middlewareResult.bindArgsParsedInputs = parsedInputDatas.slice(0, -1); } } catch (e) { if (e instanceof ActionServerValidationError) { const ve = e.validationErrors; middlewareResult.validationErrors = await Promise.resolve( args.handleValidationErrorsShape(ve, { clientInput: clientInputs.at(-1), bindArgsClientInputs: bindArgsSchemas.length ? clientInputs.slice(0, -1) : [], ctx: currentCtx, metadata: args.metadata, }) ); } else { const error = isError(e) ? e : new Error(DEFAULT_SERVER_ERROR_MESSAGE); const returnedError = await Promise.resolve( args.handleServerError(error, { clientInput: clientInputs.at(-1), // pass raw client input bindArgsClientInputs: bindArgsSchemas.length ? clientInputs.slice(0, -1) : [], ctx: currentCtx, metadata: args.metadata, }) ); middlewareResult.serverError = returnedError; } } }; await executeMiddlewareStack(); const callbackPromises = []; if (frameworkErrorHandler.error) { callbackPromises.push( utils?.onNavigation?.({ metadata: args.metadata, ctx: currentCtx, clientInput: clientInputs.at(-1), bindArgsClientInputs: bindArgsSchemas.length ? clientInputs.slice(0, -1) : [], navigationKind: FrameworkErrorHandler.getNavigationKind(frameworkErrorHandler.error), }) ); callbackPromises.push( utils?.onSettled?.({ metadata: args.metadata, ctx: currentCtx, clientInput: clientInputs.at(-1), bindArgsClientInputs: bindArgsSchemas.length ? clientInputs.slice(0, -1) : [], result: {}, navigationKind: FrameworkErrorHandler.getNavigationKind(frameworkErrorHandler.error), }) ); await Promise.all(callbackPromises); throw frameworkErrorHandler.error; } const actionResult = {}; if (typeof middlewareResult.validationErrors !== "undefined") { if ( winningBoolean( args.throwValidationErrors, typeof utils?.throwValidationErrors === "undefined" ? void 0 : Boolean(utils.throwValidationErrors) ) ) { const overrideErrorMessageFn = typeof utils?.throwValidationErrors === "object" && utils?.throwValidationErrors.overrideErrorMessage ? utils?.throwValidationErrors.overrideErrorMessage : void 0; throw new ActionValidationError( middlewareResult.validationErrors, await overrideErrorMessageFn?.(middlewareResult.validationErrors) ); } else { actionResult.validationErrors = middlewareResult.validationErrors; } } if (typeof middlewareResult.serverError !== "undefined") { if (utils?.throwServerError) { throw middlewareResult.serverError; } else { actionResult.serverError = middlewareResult.serverError; } } if (middlewareResult.success) { if (typeof middlewareResult.data !== "undefined") { actionResult.data = middlewareResult.data; } callbackPromises.push( utils?.onSuccess?.({ metadata: args.metadata, ctx: currentCtx, data: actionResult.data, clientInput: clientInputs.at(-1), bindArgsClientInputs: bindArgsSchemas.length ? clientInputs.slice(0, -1) : [], parsedInput: parsedInputDatas.at(-1), bindArgsParsedInputs: parsedInputDatas.slice(0, -1), }) ); } else { callbackPromises.push( utils?.onError?.({ metadata: args.metadata, ctx: currentCtx, clientInput: clientInputs.at(-1), bindArgsClientInputs: bindArgsSchemas.length ? clientInputs.slice(0, -1) : [], error: actionResult, }) ); } callbackPromises.push( utils?.onSettled?.({ metadata: args.metadata, ctx: currentCtx, clientInput: clientInputs.at(-1), bindArgsClientInputs: bindArgsSchemas.length ? clientInputs.slice(0, -1) : [], result: actionResult, }) ); await Promise.all(callbackPromises); return actionResult; }; }, }; } return { /** * Define the action. * @param serverCodeFn Code that will be executed on the **server side** * * {@link https://next-safe-action.dev/docs/define-actions/instance-methods#action--stateaction See docs for more information} */ action: buildAction({ withState: false }).action, /** * Define the stateful action. To be used with the [`useStateAction`](https://next-safe-action.dev/docs/execute-actions/hooks/usestateaction) hook. * @param serverCodeFn Code that will be executed on the **server side** * * {@link https://next-safe-action.dev/docs/define-actions/instance-methods#action--stateaction See docs for more information} */ stateAction: buildAction({ withState: true }).action, }; } // src/safe-action-client.ts var SafeActionClient = class _SafeActionClient { #args; constructor(args) { this.#args = args; } /** * Use a middleware function. * @param middlewareFn Middleware function * * {@link https://next-safe-action.dev/docs/define-actions/instance-methods#use See docs for more information} */ use(middlewareFn) { return new _SafeActionClient({ ...this.#args, middlewareFns: [...this.#args.middlewareFns, middlewareFn], ctxType: {}, }); } /** * Define metadata for the action. * @param data Metadata with the same type as the return value of the [`defineMetadataSchema`](https://next-safe-action.dev/docs/define-actions/create-the-client#definemetadataschema) optional initialization function * * {@link https://next-safe-action.dev/docs/define-actions/instance-methods#metadata See docs for more information} */ metadata(data) { return new _SafeActionClient({ ...this.#args, metadata: data, metadataProvided: true, }); } /** * Define the input validation schema for the action. * @param inputSchema Input validation schema * @param utils Optional utils object * * {@link https://next-safe-action.dev/docs/define-actions/create-the-client#inputschema See docs for more information} */ inputSchema(inputSchema, utils) { return new _SafeActionClient({ ...this.#args, // @ts-expect-error inputSchemaFn: inputSchema[Symbol.toStringTag] === "AsyncFunction" ? async () => { const prevSchema = await this.#args.inputSchemaFn?.(); return inputSchema(prevSchema); } : async () => inputSchema, handleValidationErrorsShape: utils?.handleValidationErrorsShape ?? this.#args.handleValidationErrorsShape, }); } /** * @deprecated Alias for `inputSchema` method. Use that instead. */ schema = this.inputSchema; /** * Define the bind args input validation schema for the action. * @param bindArgsSchemas Bind args input validation schemas * * {@link https://next-safe-action.dev/docs/define-actions/instance-methods#bindargsschemas See docs for more information} */ bindArgsSchemas(bindArgsSchemas) { return new _SafeActionClient({ ...this.#args, bindArgsSchemas, handleValidationErrorsShape: this.#args.handleValidationErrorsShape, }); } /** * Define the output data validation schema for the action. * @param schema Output data validation schema * * {@link https://next-safe-action.dev/docs/define-actions/create-the-client#outputschema See docs for more information} */ outputSchema(dataSchema) { return new _SafeActionClient({ ...this.#args, outputSchema: dataSchema, }); } /** * Define the action. * @param serverCodeFn Code that will be executed on the **server side** * @param [cb] Optional callbacks that will be called after action execution, on the server. * * {@link https://next-safe-action.dev/docs/define-actions/instance-methods#action--stateaction See docs for more information} */ action(serverCodeFn, utils) { return actionBuilder(this.#args).action(serverCodeFn, utils); } /** * Define the stateful action. * To be used with the [`useStateAction`](https://next-safe-action.dev/docs/execute-actions/hooks/usestateaction) hook. * @param serverCodeFn Code that will be executed on the **server side** * @param [cb] Optional callbacks that will be called after action execution, on the server. * * {@link https://next-safe-action.dev/docs/define-actions/instance-methods#action--stateaction See docs for more information} */ stateAction(serverCodeFn, utils) { return actionBuilder(this.#args).stateAction(serverCodeFn, utils); } }; // src/middleware.ts var createMiddleware = () => { return { define: (middlewareFn) => middlewareFn, }; }; // src/index.ts var createSafeActionClient = (createOpts) => { const handleServerError = createOpts?.handleServerError || ((e) => { console.error("Action error:", e.message); return DEFAULT_SERVER_ERROR_MESSAGE; }); return new SafeActionClient({ middlewareFns: [async ({ next }) => next({ ctx: {} })], handleServerError, inputSchemaFn: void 0, bindArgsSchemas: [], outputSchema: void 0, ctxType: {}, metadataSchema: createOpts?.defineMetadataSchema?.() ?? void 0, metadata: void 0, defaultValidationErrorsShape: createOpts?.defaultValidationErrorsShape ?? "formatted", throwValidationErrors: Boolean(createOpts?.throwValidationErrors), handleValidationErrorsShape: async (ve) => createOpts?.defaultValidationErrorsShape === "flattened" ? flattenValidationErrors(ve) : formatValidationErrors(ve), }); }; export { ActionMetadataValidationError, ActionOutputDataValidationError, ActionValidationError, DEFAULT_SERVER_ERROR_MESSAGE, createMiddleware, createSafeActionClient, flattenValidationErrors, formatValidationErrors, returnValidationErrors, }; //# sourceMappingURL=index.mjs.map