Initial commit: New MoreminiMore website with fresh design
This commit is contained in:
14
node_modules/astro/dist/actions/consts.d.ts
generated
vendored
Normal file
14
node_modules/astro/dist/actions/consts.d.ts
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
export declare const ACTIONS_TYPES_FILE = "actions.d.ts";
|
||||
export declare const VIRTUAL_MODULE_ID = "astro:actions";
|
||||
export declare const RESOLVED_VIRTUAL_MODULE_ID: string;
|
||||
export declare const ACTIONS_ENTRYPOINT_VIRTUAL_MODULE_ID = "virtual:astro:actions/entrypoint";
|
||||
export declare const ACTIONS_RESOLVED_ENTRYPOINT_VIRTUAL_MODULE_ID: string;
|
||||
/** Used to pass data from the config to the main virtual module */
|
||||
export declare const OPTIONS_VIRTUAL_MODULE_ID = "virtual:astro:actions/options";
|
||||
export declare const RESOLVED_OPTIONS_VIRTUAL_MODULE_ID: string;
|
||||
export declare const RESOLVED_NOOP_ENTRYPOINT_VIRTUAL_MODULE_ID = "\0virtual:astro:actions/noop-entrypoint";
|
||||
export declare const ACTION_QUERY_PARAMS: {
|
||||
actionName: string;
|
||||
actionPayload: string;
|
||||
};
|
||||
export declare const ACTION_RPC_ROUTE_PATTERN = "/_actions/[...path]";
|
||||
25
node_modules/astro/dist/actions/consts.js
generated
vendored
Normal file
25
node_modules/astro/dist/actions/consts.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
const ACTIONS_TYPES_FILE = "actions.d.ts";
|
||||
const VIRTUAL_MODULE_ID = "astro:actions";
|
||||
const RESOLVED_VIRTUAL_MODULE_ID = "\0" + VIRTUAL_MODULE_ID;
|
||||
const ACTIONS_ENTRYPOINT_VIRTUAL_MODULE_ID = "virtual:astro:actions/entrypoint";
|
||||
const ACTIONS_RESOLVED_ENTRYPOINT_VIRTUAL_MODULE_ID = "\0" + ACTIONS_ENTRYPOINT_VIRTUAL_MODULE_ID;
|
||||
const OPTIONS_VIRTUAL_MODULE_ID = "virtual:astro:actions/options";
|
||||
const RESOLVED_OPTIONS_VIRTUAL_MODULE_ID = "\0" + OPTIONS_VIRTUAL_MODULE_ID;
|
||||
const RESOLVED_NOOP_ENTRYPOINT_VIRTUAL_MODULE_ID = "\0virtual:astro:actions/noop-entrypoint";
|
||||
const ACTION_QUERY_PARAMS = {
|
||||
actionName: "_action",
|
||||
actionPayload: "_astroActionPayload"
|
||||
};
|
||||
const ACTION_RPC_ROUTE_PATTERN = "/_actions/[...path]";
|
||||
export {
|
||||
ACTIONS_ENTRYPOINT_VIRTUAL_MODULE_ID,
|
||||
ACTIONS_RESOLVED_ENTRYPOINT_VIRTUAL_MODULE_ID,
|
||||
ACTIONS_TYPES_FILE,
|
||||
ACTION_QUERY_PARAMS,
|
||||
ACTION_RPC_ROUTE_PATTERN,
|
||||
OPTIONS_VIRTUAL_MODULE_ID,
|
||||
RESOLVED_NOOP_ENTRYPOINT_VIRTUAL_MODULE_ID,
|
||||
RESOLVED_OPTIONS_VIRTUAL_MODULE_ID,
|
||||
RESOLVED_VIRTUAL_MODULE_ID,
|
||||
VIRTUAL_MODULE_ID
|
||||
};
|
||||
10
node_modules/astro/dist/actions/integration.d.ts
generated
vendored
Normal file
10
node_modules/astro/dist/actions/integration.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { AstroSettings } from '../types/astro.js';
|
||||
import type { AstroIntegration } from '../types/public/integrations.js';
|
||||
/**
|
||||
* This integration is applied when the user is using Actions in their project.
|
||||
* It will inject the necessary routes and middlewares to handle actions.
|
||||
*/
|
||||
export default function astroIntegrationActionsRouteHandler({ settings, filename, }: {
|
||||
settings: AstroSettings;
|
||||
filename: string;
|
||||
}): AstroIntegration;
|
||||
44
node_modules/astro/dist/actions/integration.js
generated
vendored
Normal file
44
node_modules/astro/dist/actions/integration.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
import { AstroError } from "../core/errors/errors.js";
|
||||
import { ActionsWithoutServerOutputError } from "../core/errors/errors-data.js";
|
||||
import { hasNonPrerenderedRoute } from "../core/routing/helpers.js";
|
||||
import { viteID } from "../core/util.js";
|
||||
import { ACTION_RPC_ROUTE_PATTERN, ACTIONS_TYPES_FILE, VIRTUAL_MODULE_ID } from "./consts.js";
|
||||
function astroIntegrationActionsRouteHandler({
|
||||
settings,
|
||||
filename
|
||||
}) {
|
||||
return {
|
||||
name: VIRTUAL_MODULE_ID,
|
||||
hooks: {
|
||||
async "astro:config:setup"() {
|
||||
settings.injectedRoutes.push({
|
||||
pattern: ACTION_RPC_ROUTE_PATTERN,
|
||||
entrypoint: "astro/actions/runtime/entrypoints/route.js",
|
||||
prerender: false,
|
||||
origin: "internal"
|
||||
});
|
||||
},
|
||||
"astro:config:done": async (params) => {
|
||||
const stringifiedActionsImport = JSON.stringify(
|
||||
viteID(new URL(`./${filename}`, params.config.srcDir))
|
||||
);
|
||||
settings.injectedTypes.push({
|
||||
filename: ACTIONS_TYPES_FILE,
|
||||
content: `declare module "astro:actions" {
|
||||
export const actions: typeof import(${stringifiedActionsImport})["server"];
|
||||
}`
|
||||
});
|
||||
},
|
||||
"astro:routes:resolved": ({ routes }) => {
|
||||
if (!settings.config.adapter && !hasNonPrerenderedRoute(routes)) {
|
||||
const error = new AstroError(ActionsWithoutServerOutputError);
|
||||
error.stack = void 0;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
astroIntegrationActionsRouteHandler as default
|
||||
};
|
||||
2
node_modules/astro/dist/actions/noop-actions.d.ts
generated
vendored
Normal file
2
node_modules/astro/dist/actions/noop-actions.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { SSRActions } from '../core/app/types.js';
|
||||
export declare const NOOP_ACTIONS_MOD: SSRActions;
|
||||
6
node_modules/astro/dist/actions/noop-actions.js
generated
vendored
Normal file
6
node_modules/astro/dist/actions/noop-actions.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
const NOOP_ACTIONS_MOD = {
|
||||
server: {}
|
||||
};
|
||||
export {
|
||||
NOOP_ACTIONS_MOD
|
||||
};
|
||||
84
node_modules/astro/dist/actions/runtime/client.d.ts
generated
vendored
Normal file
84
node_modules/astro/dist/actions/runtime/client.d.ts
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
import type * as z from 'zod/v4/core';
|
||||
import type { ActionClient, ActionErrorCode, ErrorInferenceObject, SafeResult, SerializedActionResult } from './types.js';
|
||||
import type { APIContext } from '../../types/public/context.js';
|
||||
export declare const codeToStatusMap: {
|
||||
BAD_REQUEST: number;
|
||||
UNAUTHORIZED: number;
|
||||
PAYMENT_REQUIRED: number;
|
||||
FORBIDDEN: number;
|
||||
NOT_FOUND: number;
|
||||
METHOD_NOT_ALLOWED: number;
|
||||
NOT_ACCEPTABLE: number;
|
||||
PROXY_AUTHENTICATION_REQUIRED: number;
|
||||
REQUEST_TIMEOUT: number;
|
||||
CONFLICT: number;
|
||||
GONE: number;
|
||||
LENGTH_REQUIRED: number;
|
||||
PRECONDITION_FAILED: number;
|
||||
CONTENT_TOO_LARGE: number;
|
||||
URI_TOO_LONG: number;
|
||||
UNSUPPORTED_MEDIA_TYPE: number;
|
||||
RANGE_NOT_SATISFIABLE: number;
|
||||
EXPECTATION_FAILED: number;
|
||||
MISDIRECTED_REQUEST: number;
|
||||
UNPROCESSABLE_CONTENT: number;
|
||||
LOCKED: number;
|
||||
FAILED_DEPENDENCY: number;
|
||||
TOO_EARLY: number;
|
||||
UPGRADE_REQUIRED: number;
|
||||
PRECONDITION_REQUIRED: number;
|
||||
TOO_MANY_REQUESTS: number;
|
||||
REQUEST_HEADER_FIELDS_TOO_LARGE: number;
|
||||
UNAVAILABLE_FOR_LEGAL_REASONS: number;
|
||||
INTERNAL_SERVER_ERROR: number;
|
||||
NOT_IMPLEMENTED: number;
|
||||
BAD_GATEWAY: number;
|
||||
SERVICE_UNAVAILABLE: number;
|
||||
GATEWAY_TIMEOUT: number;
|
||||
HTTP_VERSION_NOT_SUPPORTED: number;
|
||||
VARIANT_ALSO_NEGOTIATES: number;
|
||||
INSUFFICIENT_STORAGE: number;
|
||||
LOOP_DETECTED: number;
|
||||
NETWORK_AUTHENTICATION_REQUIRED: number;
|
||||
};
|
||||
export declare class ActionError<_T extends ErrorInferenceObject = ErrorInferenceObject> extends Error {
|
||||
type: string;
|
||||
code: ActionErrorCode;
|
||||
status: number;
|
||||
constructor(params: {
|
||||
message?: string;
|
||||
code: ActionErrorCode;
|
||||
stack?: string;
|
||||
});
|
||||
static codeToStatus(code: ActionErrorCode): number;
|
||||
static statusToCode(status: number): ActionErrorCode;
|
||||
static fromJson(body: any): ActionError<ErrorInferenceObject>;
|
||||
}
|
||||
export declare function isActionError(error?: unknown): error is ActionError;
|
||||
export declare function isInputError<T extends ErrorInferenceObject>(error?: ActionError<T>): error is ActionInputError<T>;
|
||||
export declare function isInputError(error?: unknown): error is ActionInputError<ErrorInferenceObject>;
|
||||
export declare class ActionInputError<T extends ErrorInferenceObject> extends ActionError {
|
||||
type: string;
|
||||
issues: z.$ZodIssue[];
|
||||
fields: {
|
||||
[P in keyof T]?: string[] | undefined;
|
||||
};
|
||||
constructor(issues: z.$ZodIssue[]);
|
||||
}
|
||||
export declare function deserializeActionResult(res: SerializedActionResult): SafeResult<any, any>;
|
||||
export declare const actionResultErrorStack: {
|
||||
set(stack: string | undefined): void;
|
||||
get(): string | undefined;
|
||||
};
|
||||
export declare function getActionQueryString(name: string): string;
|
||||
export declare function getActionPathFromString({ baseUrl, shouldAppendTrailingSlash, path: input, }: {
|
||||
baseUrl: string;
|
||||
shouldAppendTrailingSlash: boolean;
|
||||
path: string;
|
||||
}): string;
|
||||
export declare function createGetActionPath(options: Pick<Parameters<typeof getActionPathFromString>[0], 'baseUrl' | 'shouldAppendTrailingSlash'>): (action: ActionClient<any, any, any>) => string;
|
||||
export declare function createActionsProxy({ actionCallback, aggregatedPath, handleAction, }: {
|
||||
actionCallback?: Record<string | symbol, any>;
|
||||
aggregatedPath?: string;
|
||||
handleAction: (param: any, path: string, context: APIContext | undefined) => Promise<SafeResult<any, any>>;
|
||||
}): Record<string | symbol, any>;
|
||||
240
node_modules/astro/dist/actions/runtime/client.js
generated
vendored
Normal file
240
node_modules/astro/dist/actions/runtime/client.js
generated
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
import { parse as devalueParse } from "devalue";
|
||||
import { ACTION_QUERY_PARAMS } from "../consts.js";
|
||||
import { appendForwardSlash } from "../../core/path.js";
|
||||
const codeToStatusMap = {
|
||||
// Implemented from IANA HTTP Status Code Registry
|
||||
// https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
|
||||
BAD_REQUEST: 400,
|
||||
UNAUTHORIZED: 401,
|
||||
PAYMENT_REQUIRED: 402,
|
||||
FORBIDDEN: 403,
|
||||
NOT_FOUND: 404,
|
||||
METHOD_NOT_ALLOWED: 405,
|
||||
NOT_ACCEPTABLE: 406,
|
||||
PROXY_AUTHENTICATION_REQUIRED: 407,
|
||||
REQUEST_TIMEOUT: 408,
|
||||
CONFLICT: 409,
|
||||
GONE: 410,
|
||||
LENGTH_REQUIRED: 411,
|
||||
PRECONDITION_FAILED: 412,
|
||||
CONTENT_TOO_LARGE: 413,
|
||||
URI_TOO_LONG: 414,
|
||||
UNSUPPORTED_MEDIA_TYPE: 415,
|
||||
RANGE_NOT_SATISFIABLE: 416,
|
||||
EXPECTATION_FAILED: 417,
|
||||
MISDIRECTED_REQUEST: 421,
|
||||
UNPROCESSABLE_CONTENT: 422,
|
||||
LOCKED: 423,
|
||||
FAILED_DEPENDENCY: 424,
|
||||
TOO_EARLY: 425,
|
||||
UPGRADE_REQUIRED: 426,
|
||||
PRECONDITION_REQUIRED: 428,
|
||||
TOO_MANY_REQUESTS: 429,
|
||||
REQUEST_HEADER_FIELDS_TOO_LARGE: 431,
|
||||
UNAVAILABLE_FOR_LEGAL_REASONS: 451,
|
||||
INTERNAL_SERVER_ERROR: 500,
|
||||
NOT_IMPLEMENTED: 501,
|
||||
BAD_GATEWAY: 502,
|
||||
SERVICE_UNAVAILABLE: 503,
|
||||
GATEWAY_TIMEOUT: 504,
|
||||
HTTP_VERSION_NOT_SUPPORTED: 505,
|
||||
VARIANT_ALSO_NEGOTIATES: 506,
|
||||
INSUFFICIENT_STORAGE: 507,
|
||||
LOOP_DETECTED: 508,
|
||||
NETWORK_AUTHENTICATION_REQUIRED: 511
|
||||
};
|
||||
const statusToCodeMap = Object.fromEntries(
|
||||
Object.entries(codeToStatusMap).map(([key, value]) => [value, key])
|
||||
);
|
||||
class ActionError extends Error {
|
||||
type = "AstroActionError";
|
||||
code = "INTERNAL_SERVER_ERROR";
|
||||
status = 500;
|
||||
constructor(params) {
|
||||
super(params.message);
|
||||
this.code = params.code;
|
||||
this.status = ActionError.codeToStatus(params.code);
|
||||
if (params.stack) {
|
||||
this.stack = params.stack;
|
||||
}
|
||||
}
|
||||
static codeToStatus(code) {
|
||||
return codeToStatusMap[code];
|
||||
}
|
||||
static statusToCode(status) {
|
||||
return statusToCodeMap[status] ?? "INTERNAL_SERVER_ERROR";
|
||||
}
|
||||
static fromJson(body) {
|
||||
if (isInputError(body)) {
|
||||
return new ActionInputError(body.issues);
|
||||
}
|
||||
if (isActionError(body)) {
|
||||
return new ActionError(body);
|
||||
}
|
||||
return new ActionError({
|
||||
code: "INTERNAL_SERVER_ERROR"
|
||||
});
|
||||
}
|
||||
}
|
||||
function isActionError(error) {
|
||||
return typeof error === "object" && error != null && "type" in error && error.type === "AstroActionError";
|
||||
}
|
||||
function isInputError(error) {
|
||||
return typeof error === "object" && error != null && "type" in error && error.type === "AstroActionInputError" && "issues" in error && Array.isArray(error.issues);
|
||||
}
|
||||
class ActionInputError extends ActionError {
|
||||
type = "AstroActionInputError";
|
||||
// We don't expose all ZodError properties.
|
||||
// Not all properties will serialize from server to client,
|
||||
// and we don't want to import the full ZodError object into the client.
|
||||
issues;
|
||||
fields;
|
||||
constructor(issues) {
|
||||
super({
|
||||
message: `Failed to validate: ${JSON.stringify(issues, null, 2)}`,
|
||||
code: "BAD_REQUEST"
|
||||
});
|
||||
this.issues = issues;
|
||||
this.fields = {};
|
||||
for (const issue of issues) {
|
||||
if (issue.path.length > 0) {
|
||||
const key = issue.path[0].toString();
|
||||
this.fields[key] ??= [];
|
||||
this.fields[key]?.push(issue.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function deserializeActionResult(res) {
|
||||
if (res.type === "error") {
|
||||
let json;
|
||||
try {
|
||||
json = JSON.parse(res.body);
|
||||
} catch {
|
||||
return {
|
||||
data: void 0,
|
||||
error: new ActionError({
|
||||
message: res.body,
|
||||
code: "INTERNAL_SERVER_ERROR"
|
||||
})
|
||||
};
|
||||
}
|
||||
if (import.meta.env?.PROD) {
|
||||
return { error: ActionError.fromJson(json), data: void 0 };
|
||||
} else {
|
||||
const error = ActionError.fromJson(json);
|
||||
error.stack = actionResultErrorStack.get();
|
||||
return {
|
||||
error,
|
||||
data: void 0
|
||||
};
|
||||
}
|
||||
}
|
||||
if (res.type === "empty") {
|
||||
return { data: void 0, error: void 0 };
|
||||
}
|
||||
return {
|
||||
data: devalueParse(res.body, {
|
||||
URL: (href) => new URL(href)
|
||||
}),
|
||||
error: void 0
|
||||
};
|
||||
}
|
||||
const actionResultErrorStack = /* @__PURE__ */ (function actionResultErrorStackFn() {
|
||||
let errorStack;
|
||||
return {
|
||||
set(stack) {
|
||||
errorStack = stack;
|
||||
},
|
||||
get() {
|
||||
return errorStack;
|
||||
}
|
||||
};
|
||||
})();
|
||||
function getActionQueryString(name) {
|
||||
const searchParams = new URLSearchParams({ [ACTION_QUERY_PARAMS.actionName]: name });
|
||||
return `?${searchParams.toString()}`;
|
||||
}
|
||||
function getActionPathFromString({
|
||||
baseUrl,
|
||||
shouldAppendTrailingSlash,
|
||||
path: input
|
||||
}) {
|
||||
let path = `${baseUrl.replace(/\/$/, "")}/_actions/${new URLSearchParams(input).get(ACTION_QUERY_PARAMS.actionName)}`;
|
||||
if (shouldAppendTrailingSlash) {
|
||||
path = appendForwardSlash(path);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
function createGetActionPath(options) {
|
||||
return function getActionPath(action) {
|
||||
return getActionPathFromString({
|
||||
baseUrl: options.baseUrl,
|
||||
shouldAppendTrailingSlash: options.shouldAppendTrailingSlash,
|
||||
path: action.toString()
|
||||
});
|
||||
};
|
||||
}
|
||||
const ENCODED_DOT = "%2E";
|
||||
function createActionsProxy({
|
||||
actionCallback = {},
|
||||
aggregatedPath = "",
|
||||
handleAction
|
||||
}) {
|
||||
return new Proxy(actionCallback, {
|
||||
get(target, objKey) {
|
||||
if (target.hasOwnProperty(objKey) || typeof objKey === "symbol") {
|
||||
return target[objKey];
|
||||
}
|
||||
const path = aggregatedPath + encodeURIComponent(objKey.toString()).replaceAll(".", ENCODED_DOT);
|
||||
function action(param) {
|
||||
return handleAction(param, path, this);
|
||||
}
|
||||
Object.assign(action, {
|
||||
queryString: getActionQueryString(path),
|
||||
toString: () => action.queryString,
|
||||
// redefine prototype methods as the object's own property, not the prototype's
|
||||
bind: action.bind,
|
||||
valueOf: () => action.valueOf,
|
||||
// Progressive enhancement info for React.
|
||||
$$FORM_ACTION: function() {
|
||||
const searchParams = new URLSearchParams(action.toString());
|
||||
return {
|
||||
method: "POST",
|
||||
// `name` creates a hidden input.
|
||||
// It's unused by Astro, but we can't turn this off.
|
||||
// At least use a name that won't conflict with a user's formData.
|
||||
name: "_astroAction",
|
||||
action: "?" + searchParams.toString()
|
||||
};
|
||||
},
|
||||
// Note: `orThrow` does not have progressive enhancement info.
|
||||
// If you want to throw exceptions,
|
||||
// you must handle those exceptions with client JS.
|
||||
async orThrow(param) {
|
||||
const { data, error } = await handleAction(param, path, this);
|
||||
if (error) throw error;
|
||||
return data;
|
||||
}
|
||||
});
|
||||
return createActionsProxy({
|
||||
actionCallback: action,
|
||||
aggregatedPath: path + ".",
|
||||
handleAction
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
export {
|
||||
ActionError,
|
||||
ActionInputError,
|
||||
actionResultErrorStack,
|
||||
codeToStatusMap,
|
||||
createActionsProxy,
|
||||
createGetActionPath,
|
||||
deserializeActionResult,
|
||||
getActionPathFromString,
|
||||
getActionQueryString,
|
||||
isActionError,
|
||||
isInputError
|
||||
};
|
||||
7
node_modules/astro/dist/actions/runtime/entrypoints/client.d.ts
generated
vendored
Normal file
7
node_modules/astro/dist/actions/runtime/entrypoints/client.d.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export { ACTION_QUERY_PARAMS } from '../../consts.js';
|
||||
export { ActionError, isActionError, isInputError, } from '../client.js';
|
||||
export type { ActionAPIContext, ActionClient, ActionErrorCode, ActionInputSchema, ActionReturnType, SafeResult, } from '../types.js';
|
||||
export declare function defineAction(): void;
|
||||
export declare function getActionContext(): void;
|
||||
export declare const getActionPath: (action: import("../types.js").ActionClient<any, any, any>) => string;
|
||||
export declare const actions: Record<string | symbol, any>;
|
||||
91
node_modules/astro/dist/actions/runtime/entrypoints/client.js
generated
vendored
Normal file
91
node_modules/astro/dist/actions/runtime/entrypoints/client.js
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
import { shouldAppendTrailingSlash } from "virtual:astro:actions/options";
|
||||
import { internalFetchHeaders } from "virtual:astro:adapter-config/client";
|
||||
import {
|
||||
ActionError,
|
||||
createActionsProxy,
|
||||
createGetActionPath,
|
||||
deserializeActionResult,
|
||||
getActionPathFromString,
|
||||
getActionQueryString
|
||||
} from "../client.js";
|
||||
import { ACTION_QUERY_PARAMS } from "../../consts.js";
|
||||
import {
|
||||
ActionError as ActionError2,
|
||||
isActionError,
|
||||
isInputError
|
||||
} from "../client.js";
|
||||
function defineAction() {
|
||||
throw new Error("[astro:actions] `defineAction()` unexpectedly used on the client.");
|
||||
}
|
||||
function getActionContext() {
|
||||
throw new Error("[astro:actions] `getActionContext()` unexpectedly used on the client.");
|
||||
}
|
||||
const getActionPath = createGetActionPath({
|
||||
baseUrl: import.meta.env.BASE_URL,
|
||||
shouldAppendTrailingSlash
|
||||
});
|
||||
const actions = createActionsProxy({
|
||||
handleAction: async (param, path) => {
|
||||
const headers = new Headers();
|
||||
headers.set("Accept", "application/json");
|
||||
for (const [key, value] of Object.entries(internalFetchHeaders)) {
|
||||
headers.set(key, value);
|
||||
}
|
||||
let body = param;
|
||||
if (!(body instanceof FormData)) {
|
||||
try {
|
||||
body = JSON.stringify(param);
|
||||
} catch (e) {
|
||||
throw new ActionError({
|
||||
code: "BAD_REQUEST",
|
||||
message: `Failed to serialize request body to JSON. Full error: ${e.message}`
|
||||
});
|
||||
}
|
||||
if (body) {
|
||||
headers.set("Content-Type", "application/json");
|
||||
} else {
|
||||
headers.set("Content-Length", "0");
|
||||
}
|
||||
}
|
||||
const rawResult = await fetch(
|
||||
getActionPathFromString({
|
||||
baseUrl: import.meta.env.BASE_URL,
|
||||
shouldAppendTrailingSlash,
|
||||
path: getActionQueryString(path)
|
||||
}),
|
||||
{
|
||||
method: "POST",
|
||||
body,
|
||||
headers
|
||||
}
|
||||
);
|
||||
if (rawResult.status === 204) {
|
||||
return deserializeActionResult({ type: "empty", status: 204 });
|
||||
}
|
||||
const bodyText = await rawResult.text();
|
||||
if (rawResult.ok) {
|
||||
return deserializeActionResult({
|
||||
type: "data",
|
||||
body: bodyText,
|
||||
status: 200,
|
||||
contentType: "application/json+devalue"
|
||||
});
|
||||
}
|
||||
return deserializeActionResult({
|
||||
type: "error",
|
||||
body: bodyText,
|
||||
status: rawResult.status,
|
||||
contentType: "application/json"
|
||||
});
|
||||
}
|
||||
});
|
||||
export {
|
||||
ACTION_QUERY_PARAMS,
|
||||
ActionError2 as ActionError,
|
||||
actions,
|
||||
defineAction,
|
||||
getActionContext,
|
||||
getActionPath,
|
||||
isActionError,
|
||||
isInputError
|
||||
};
|
||||
2
node_modules/astro/dist/actions/runtime/entrypoints/route.d.ts
generated
vendored
Normal file
2
node_modules/astro/dist/actions/runtime/entrypoints/route.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { APIRoute } from '../../../types/public/common.js';
|
||||
export declare const POST: APIRoute;
|
||||
23
node_modules/astro/dist/actions/runtime/entrypoints/route.js
generated
vendored
Normal file
23
node_modules/astro/dist/actions/runtime/entrypoints/route.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import { getActionContext } from "../server.js";
|
||||
const POST = async (context) => {
|
||||
const { action, serializeActionResult } = getActionContext(context);
|
||||
if (action?.calledFrom !== "rpc") {
|
||||
return new Response("Not found", { status: 404 });
|
||||
}
|
||||
const result = await action.handler();
|
||||
const serialized = serializeActionResult(result);
|
||||
if (serialized.type === "empty") {
|
||||
return new Response(null, {
|
||||
status: serialized.status
|
||||
});
|
||||
}
|
||||
return new Response(serialized.body, {
|
||||
status: serialized.status,
|
||||
headers: {
|
||||
"Content-Type": serialized.contentType
|
||||
}
|
||||
});
|
||||
};
|
||||
export {
|
||||
POST
|
||||
};
|
||||
6
node_modules/astro/dist/actions/runtime/entrypoints/server.d.ts
generated
vendored
Normal file
6
node_modules/astro/dist/actions/runtime/entrypoints/server.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
export { ACTION_QUERY_PARAMS } from '../../consts.js';
|
||||
export { ActionError, isActionError, isInputError } from '../client.js';
|
||||
export { defineAction, getActionContext } from '../server.js';
|
||||
export type { ActionAPIContext, ActionClient, ActionErrorCode, ActionInputSchema, ActionReturnType, SafeResult, } from '../types.js';
|
||||
export declare const getActionPath: (action: import("../types.js").ActionClient<any, any, any>) => string;
|
||||
export declare const actions: Record<string | symbol, any>;
|
||||
33
node_modules/astro/dist/actions/runtime/entrypoints/server.js
generated
vendored
Normal file
33
node_modules/astro/dist/actions/runtime/entrypoints/server.js
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
import { pipelineSymbol } from "../../../core/constants.js";
|
||||
import { ActionCalledFromServerError } from "../../../core/errors/errors-data.js";
|
||||
import { AstroError } from "../../../core/errors/errors.js";
|
||||
import { createGetActionPath, createActionsProxy } from "../client.js";
|
||||
import { shouldAppendTrailingSlash } from "virtual:astro:actions/options";
|
||||
import { ACTION_QUERY_PARAMS } from "../../consts.js";
|
||||
import { ActionError, isActionError, isInputError } from "../client.js";
|
||||
import { defineAction, getActionContext } from "../server.js";
|
||||
const getActionPath = createGetActionPath({
|
||||
baseUrl: import.meta.env.BASE_URL,
|
||||
shouldAppendTrailingSlash
|
||||
});
|
||||
const actions = createActionsProxy({
|
||||
handleAction: async (param, path, context) => {
|
||||
const pipeline = context ? Reflect.get(context, pipelineSymbol) : void 0;
|
||||
if (!pipeline) {
|
||||
throw new AstroError(ActionCalledFromServerError);
|
||||
}
|
||||
const action = await pipeline.getAction(path);
|
||||
if (!action) throw new Error(`Action not found: ${path}`);
|
||||
return action.bind(context)(param);
|
||||
}
|
||||
});
|
||||
export {
|
||||
ACTION_QUERY_PARAMS,
|
||||
ActionError,
|
||||
actions,
|
||||
defineAction,
|
||||
getActionContext,
|
||||
getActionPath,
|
||||
isActionError,
|
||||
isInputError
|
||||
};
|
||||
45
node_modules/astro/dist/actions/runtime/server.d.ts
generated
vendored
Normal file
45
node_modules/astro/dist/actions/runtime/server.d.ts
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
import * as z from 'zod/v4/core';
|
||||
import type { APIContext } from '../../types/public/index.js';
|
||||
import { deserializeActionResult } from './client.js';
|
||||
import type { ActionAccept, ActionClient, ActionHandler, SafeResult, SerializedActionResult } from './types.js';
|
||||
export declare function defineAction<TOutput, TAccept extends ActionAccept | undefined = undefined, TInputSchema extends z.$ZodType | undefined = TAccept extends 'form' ? z.$ZodType<FormData> : undefined>({ accept, input: inputSchema, handler, }: {
|
||||
input?: TInputSchema;
|
||||
accept?: TAccept;
|
||||
handler: ActionHandler<TInputSchema, TOutput>;
|
||||
}): ActionClient<TOutput, TAccept, TInputSchema> & string;
|
||||
interface AstroActionContext {
|
||||
/** Information about an incoming action request. */
|
||||
action?: {
|
||||
/** Whether an action was called using an RPC function or by using an HTML form action. */
|
||||
calledFrom: 'rpc' | 'form';
|
||||
/** The name of the action. Useful to track the source of an action result during a redirect. */
|
||||
name: string;
|
||||
/** Programmatically call the action to get the result. */
|
||||
handler: () => Promise<SafeResult<any, any>>;
|
||||
};
|
||||
/**
|
||||
* Manually set the action result accessed via `getActionResult()`.
|
||||
* Calling this function from middleware will disable Astro's own action result handling.
|
||||
*/
|
||||
setActionResult(actionName: string, actionResult: SerializedActionResult): void;
|
||||
/**
|
||||
* Serialize an action result to stored in a cookie or session.
|
||||
* Also used to pass a result to Astro templates via `setActionResult()`.
|
||||
*/
|
||||
serializeActionResult: typeof serializeActionResult;
|
||||
/**
|
||||
* Deserialize an action result to access data and error objects.
|
||||
*/
|
||||
deserializeActionResult: typeof deserializeActionResult;
|
||||
}
|
||||
/**
|
||||
* Access information about Action requests from middleware.
|
||||
*/
|
||||
export declare function getActionContext(context: APIContext): AstroActionContext;
|
||||
export declare const ACTION_API_CONTEXT_SYMBOL: unique symbol;
|
||||
/** Transform form data to an object based on a Zod schema. */
|
||||
export declare function formDataToObject<T extends z.$ZodObject>(formData: FormData, schema: T,
|
||||
/** @internal */
|
||||
prefix?: string): Record<string, unknown>;
|
||||
export declare function serializeActionResult(res: SafeResult<any, any>): SerializedActionResult;
|
||||
export {};
|
||||
379
node_modules/astro/dist/actions/runtime/server.js
generated
vendored
Normal file
379
node_modules/astro/dist/actions/runtime/server.js
generated
vendored
Normal file
@@ -0,0 +1,379 @@
|
||||
import { stringify as devalueStringify } from "devalue";
|
||||
import * as z from "zod/v4/core";
|
||||
import { shouldAppendForwardSlash } from "../../core/build/util.js";
|
||||
import { pipelineSymbol, REDIRECT_STATUS_CODES } from "../../core/constants.js";
|
||||
import {
|
||||
ActionCalledFromServerError,
|
||||
ActionNotFoundError,
|
||||
ActionsReturnedInvalidDataError
|
||||
} from "../../core/errors/errors-data.js";
|
||||
import { AstroError } from "../../core/errors/errors.js";
|
||||
import { removeTrailingForwardSlash } from "../../core/path.js";
|
||||
import { BodySizeLimitError, readBodyWithLimit } from "../../core/request-body.js";
|
||||
import { ACTION_QUERY_PARAMS, ACTION_RPC_ROUTE_PATTERN } from "../consts.js";
|
||||
import {
|
||||
ActionError,
|
||||
ActionInputError,
|
||||
actionResultErrorStack,
|
||||
deserializeActionResult
|
||||
} from "./client.js";
|
||||
function defineAction({
|
||||
accept,
|
||||
input: inputSchema,
|
||||
handler
|
||||
}) {
|
||||
const serverHandler = accept === "form" ? getFormServerHandler(handler, inputSchema) : getJsonServerHandler(handler, inputSchema);
|
||||
async function safeServerHandler(unparsedInput) {
|
||||
if (typeof this === "function" || !isActionAPIContext(this)) {
|
||||
throw new AstroError(ActionCalledFromServerError);
|
||||
}
|
||||
return callSafely(() => serverHandler(unparsedInput, this));
|
||||
}
|
||||
Object.assign(safeServerHandler, {
|
||||
orThrow(unparsedInput) {
|
||||
if (typeof this === "function") {
|
||||
throw new AstroError(ActionCalledFromServerError);
|
||||
}
|
||||
return serverHandler(unparsedInput, this);
|
||||
}
|
||||
});
|
||||
return safeServerHandler;
|
||||
}
|
||||
function getFormServerHandler(handler, inputSchema) {
|
||||
return async (unparsedInput, context) => {
|
||||
if (!(unparsedInput instanceof FormData)) {
|
||||
throw new ActionError({
|
||||
code: "UNSUPPORTED_MEDIA_TYPE",
|
||||
message: "This action only accepts FormData."
|
||||
});
|
||||
}
|
||||
if (!inputSchema) return await handler(unparsedInput, context);
|
||||
const parsed = await parseFormInput(inputSchema, unparsedInput);
|
||||
if (!parsed.success) {
|
||||
throw new ActionInputError(parsed.error.issues);
|
||||
}
|
||||
return await handler(parsed.data, context);
|
||||
};
|
||||
}
|
||||
async function parseFormInput(inputSchema, unparsedInput) {
|
||||
const baseSchema = unwrapBaseZ4ObjectSchema(inputSchema, unparsedInput);
|
||||
const input = baseSchema instanceof z.$ZodObject ? formDataToObject(unparsedInput, baseSchema) : unparsedInput;
|
||||
const parsed = await z.safeParseAsync(inputSchema, input);
|
||||
return parsed;
|
||||
}
|
||||
function getJsonServerHandler(handler, inputSchema) {
|
||||
return async (unparsedInput, context) => {
|
||||
if (unparsedInput instanceof FormData) {
|
||||
throw new ActionError({
|
||||
code: "UNSUPPORTED_MEDIA_TYPE",
|
||||
message: "This action only accepts JSON."
|
||||
});
|
||||
}
|
||||
if (!inputSchema) return await handler(unparsedInput, context);
|
||||
const parsed = await z.safeParseAsync(inputSchema, unparsedInput);
|
||||
if (!parsed.success) {
|
||||
throw new ActionInputError(parsed.error.issues);
|
||||
}
|
||||
return await handler(parsed.data, context);
|
||||
};
|
||||
}
|
||||
function getActionContext(context) {
|
||||
const callerInfo = getCallerInfo(context);
|
||||
const actionResultAlreadySet = Boolean(context.locals._actionPayload);
|
||||
let action = void 0;
|
||||
if (callerInfo && context.request.method === "POST" && !actionResultAlreadySet) {
|
||||
action = {
|
||||
calledFrom: callerInfo.from,
|
||||
name: callerInfo.name,
|
||||
handler: async () => {
|
||||
const pipeline = Reflect.get(context, pipelineSymbol);
|
||||
const callerInfoName = shouldAppendForwardSlash(
|
||||
pipeline.manifest.trailingSlash,
|
||||
pipeline.manifest.buildFormat
|
||||
) ? removeTrailingForwardSlash(callerInfo.name) : callerInfo.name;
|
||||
let baseAction;
|
||||
try {
|
||||
baseAction = await pipeline.getAction(callerInfoName);
|
||||
} catch (error) {
|
||||
if (error instanceof Error && "name" in error && typeof error.name === "string" && error.name === ActionNotFoundError.name) {
|
||||
return { data: void 0, error: new ActionError({ code: "NOT_FOUND" }) };
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
const bodySizeLimit = pipeline.manifest.actionBodySizeLimit;
|
||||
let input;
|
||||
try {
|
||||
input = await parseRequestBody(context.request, bodySizeLimit);
|
||||
} catch (e) {
|
||||
if (e instanceof ActionError) {
|
||||
return { data: void 0, error: e };
|
||||
}
|
||||
if (e instanceof TypeError) {
|
||||
return { data: void 0, error: new ActionError({ code: "UNSUPPORTED_MEDIA_TYPE" }) };
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
const omitKeys = ["props", "getActionResult", "callAction", "redirect"];
|
||||
const actionAPIContext = Object.create(
|
||||
Object.getPrototypeOf(context),
|
||||
Object.fromEntries(
|
||||
Object.entries(Object.getOwnPropertyDescriptors(context)).filter(
|
||||
([key]) => !omitKeys.includes(key)
|
||||
)
|
||||
)
|
||||
);
|
||||
Reflect.set(actionAPIContext, ACTION_API_CONTEXT_SYMBOL, true);
|
||||
const handler = baseAction.bind(actionAPIContext);
|
||||
return handler(input);
|
||||
}
|
||||
};
|
||||
}
|
||||
function setActionResult(actionName, actionResult) {
|
||||
context.locals._actionPayload = {
|
||||
actionResult,
|
||||
actionName
|
||||
};
|
||||
}
|
||||
return {
|
||||
action,
|
||||
setActionResult,
|
||||
serializeActionResult,
|
||||
deserializeActionResult
|
||||
};
|
||||
}
|
||||
function getCallerInfo(ctx) {
|
||||
if (ctx.routePattern === ACTION_RPC_ROUTE_PATTERN) {
|
||||
return { from: "rpc", name: ctx.url.pathname.replace(/^.*\/_actions\//, "") };
|
||||
}
|
||||
const queryParam = ctx.url.searchParams.get(ACTION_QUERY_PARAMS.actionName);
|
||||
if (queryParam) {
|
||||
return { from: "form", name: queryParam };
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
async function parseRequestBody(request, bodySizeLimit) {
|
||||
const contentType = request.headers.get("content-type");
|
||||
const contentLengthHeader = request.headers.get("content-length");
|
||||
const contentLength = contentLengthHeader ? Number.parseInt(contentLengthHeader, 10) : void 0;
|
||||
const hasContentLength = typeof contentLength === "number" && Number.isFinite(contentLength);
|
||||
if (!contentType) return void 0;
|
||||
if (hasContentLength && contentLength > bodySizeLimit) {
|
||||
throw new ActionError({
|
||||
code: "CONTENT_TOO_LARGE",
|
||||
message: `Request body exceeds ${bodySizeLimit} bytes`
|
||||
});
|
||||
}
|
||||
try {
|
||||
if (hasContentType(contentType, formContentTypes)) {
|
||||
if (!hasContentLength) {
|
||||
const body = await readBodyWithLimit(request.clone(), bodySizeLimit);
|
||||
const formRequest = new Request(request.url, {
|
||||
method: request.method,
|
||||
headers: request.headers,
|
||||
body: toArrayBuffer(body)
|
||||
});
|
||||
return await formRequest.formData();
|
||||
}
|
||||
return await request.clone().formData();
|
||||
}
|
||||
if (hasContentType(contentType, ["application/json"])) {
|
||||
if (contentLength === 0) return void 0;
|
||||
if (!hasContentLength) {
|
||||
const body = await readBodyWithLimit(request.clone(), bodySizeLimit);
|
||||
if (body.byteLength === 0) return void 0;
|
||||
return JSON.parse(new TextDecoder().decode(body));
|
||||
}
|
||||
return await request.clone().json();
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof BodySizeLimitError) {
|
||||
throw new ActionError({
|
||||
code: "CONTENT_TOO_LARGE",
|
||||
message: `Request body exceeds ${bodySizeLimit} bytes`
|
||||
});
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
throw new TypeError("Unsupported content type");
|
||||
}
|
||||
const ACTION_API_CONTEXT_SYMBOL = /* @__PURE__ */ Symbol.for("astro.actionAPIContext");
|
||||
const formContentTypes = ["application/x-www-form-urlencoded", "multipart/form-data"];
|
||||
function hasContentType(contentType, expected) {
|
||||
const type = contentType.split(";")[0].toLowerCase();
|
||||
return expected.some((t) => type === t);
|
||||
}
|
||||
function isActionAPIContext(ctx) {
|
||||
const symbol = Reflect.get(ctx, ACTION_API_CONTEXT_SYMBOL);
|
||||
return symbol === true;
|
||||
}
|
||||
function formDataToObject(formData, schema, prefix = "") {
|
||||
const formKeys = [...formData.keys()];
|
||||
const obj = schema._zod.def.catchall ? Object.fromEntries(
|
||||
[...formData.entries()].filter(([k]) => k.startsWith(prefix)).map(([k, v]) => [k.slice(prefix.length), v])
|
||||
) : {};
|
||||
for (const [key, baseValidator] of Object.entries(schema._zod.def.shape)) {
|
||||
const prefixedKey = prefix + key;
|
||||
let validator = baseValidator;
|
||||
while (validator instanceof z.$ZodOptional || validator instanceof z.$ZodNullable || validator instanceof z.$ZodDefault) {
|
||||
if (validator instanceof z.$ZodDefault && !formDataHasKeyOrPrefix(formKeys, prefixedKey)) {
|
||||
obj[key] = validator._zod.def.defaultValue instanceof Function ? validator._zod.def.defaultValue() : validator._zod.def.defaultValue;
|
||||
}
|
||||
validator = validator._zod.def.innerType;
|
||||
}
|
||||
while (validator instanceof z.$ZodPipe) {
|
||||
validator = validator._zod.def.in;
|
||||
}
|
||||
if (validator instanceof z.$ZodDiscriminatedUnion) {
|
||||
const typeKey = validator._zod.def.discriminator;
|
||||
const typeValue = formData.get(prefixedKey + "." + typeKey);
|
||||
if (typeof typeValue === "string") {
|
||||
const match = validator._zod.def.options.find(
|
||||
(option) => option.def.shape[typeKey].values.has(typeValue)
|
||||
);
|
||||
if (match) {
|
||||
validator = match;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (validator instanceof z.$ZodObject) {
|
||||
const nestedPrefix = prefixedKey + ".";
|
||||
const hasNestedKeys = formKeys.some((k) => k.startsWith(nestedPrefix));
|
||||
if (hasNestedKeys) {
|
||||
obj[key] = formDataToObject(formData, validator, nestedPrefix);
|
||||
} else if (!(key in obj)) {
|
||||
obj[key] = baseValidator instanceof z.$ZodNullable ? null : void 0;
|
||||
}
|
||||
} else if (!formData.has(prefixedKey) && key in obj) {
|
||||
continue;
|
||||
} else if (validator instanceof z.$ZodBoolean) {
|
||||
const val = formData.get(prefixedKey);
|
||||
obj[key] = val === "true" ? true : val === "false" ? false : formData.has(prefixedKey);
|
||||
} else if (validator instanceof z.$ZodArray) {
|
||||
obj[key] = handleFormDataGetAll(prefixedKey, formData, validator);
|
||||
} else {
|
||||
obj[key] = handleFormDataGet(prefixedKey, formData, validator, baseValidator);
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
function formDataHasKeyOrPrefix(formKeys, key) {
|
||||
const prefix = key + ".";
|
||||
return formKeys.some((k) => k === key || k.startsWith(prefix));
|
||||
}
|
||||
function handleFormDataGetAll(key, formData, validator) {
|
||||
const entries = Array.from(formData.getAll(key));
|
||||
const elementValidator = validator._zod.def.element;
|
||||
if (elementValidator instanceof z.$ZodNumber) {
|
||||
return entries.map(Number);
|
||||
} else if (elementValidator instanceof z.$ZodBoolean) {
|
||||
return entries.map(Boolean);
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
function handleFormDataGet(key, formData, validator, baseValidator) {
|
||||
const value = formData.get(key);
|
||||
if (!value) {
|
||||
return baseValidator instanceof z.$ZodOptional ? void 0 : null;
|
||||
}
|
||||
return validator instanceof z.$ZodNumber ? Number(value) : value;
|
||||
}
|
||||
function unwrapBaseZ4ObjectSchema(schema, unparsedInput) {
|
||||
if (schema instanceof z.$ZodPipe) {
|
||||
return unwrapBaseZ4ObjectSchema(schema._zod.def.in, unparsedInput);
|
||||
}
|
||||
if (schema instanceof z.$ZodDiscriminatedUnion) {
|
||||
const typeKey = schema._zod.def.discriminator;
|
||||
const typeValue = unparsedInput.get(typeKey);
|
||||
if (typeof typeValue !== "string") return schema;
|
||||
const objSchema = schema._zod.def.options.find(
|
||||
(option) => option.def.shape[typeKey].values.has(typeValue)
|
||||
);
|
||||
if (!objSchema) return schema;
|
||||
return objSchema;
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
async function callSafely(handler) {
|
||||
try {
|
||||
const data = await handler();
|
||||
return { data, error: void 0 };
|
||||
} catch (e) {
|
||||
if (e instanceof ActionError) {
|
||||
return { data: void 0, error: e };
|
||||
}
|
||||
return {
|
||||
data: void 0,
|
||||
error: new ActionError({
|
||||
message: e instanceof Error ? e.message : "Unknown error",
|
||||
code: "INTERNAL_SERVER_ERROR"
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
||||
function serializeActionResult(res) {
|
||||
if (res.error) {
|
||||
if (import.meta.env?.DEV) {
|
||||
actionResultErrorStack.set(res.error.stack);
|
||||
}
|
||||
let body2;
|
||||
if (res.error instanceof ActionInputError) {
|
||||
body2 = {
|
||||
type: res.error.type,
|
||||
issues: res.error.issues,
|
||||
fields: res.error.fields
|
||||
};
|
||||
} else {
|
||||
body2 = {
|
||||
...res.error,
|
||||
message: res.error.message
|
||||
};
|
||||
}
|
||||
return {
|
||||
type: "error",
|
||||
status: res.error.status,
|
||||
contentType: "application/json",
|
||||
body: JSON.stringify(body2)
|
||||
};
|
||||
}
|
||||
if (res.data === void 0) {
|
||||
return {
|
||||
type: "empty",
|
||||
status: 204
|
||||
};
|
||||
}
|
||||
let body;
|
||||
try {
|
||||
body = devalueStringify(res.data, {
|
||||
// Add support for URL objects
|
||||
URL: (value) => value instanceof URL && value.href
|
||||
});
|
||||
} catch (e) {
|
||||
let hint = ActionsReturnedInvalidDataError.hint;
|
||||
if (res.data instanceof Response) {
|
||||
hint = REDIRECT_STATUS_CODES.includes(res.data.status) ? "If you need to redirect when the action succeeds, trigger a redirect where the action is called. See the Actions guide for server and client redirect examples: https://docs.astro.build/en/guides/actions." : "If you need to return a Response object, try using a server endpoint instead. See https://docs.astro.build/en/guides/endpoints/#server-endpoints-api-routes";
|
||||
}
|
||||
throw new AstroError({
|
||||
...ActionsReturnedInvalidDataError,
|
||||
message: ActionsReturnedInvalidDataError.message(String(e)),
|
||||
hint
|
||||
});
|
||||
}
|
||||
return {
|
||||
type: "data",
|
||||
status: 200,
|
||||
contentType: "application/json+devalue",
|
||||
body
|
||||
};
|
||||
}
|
||||
function toArrayBuffer(buffer) {
|
||||
const copy = new Uint8Array(buffer.byteLength);
|
||||
copy.set(buffer);
|
||||
return copy.buffer;
|
||||
}
|
||||
export {
|
||||
ACTION_API_CONTEXT_SYMBOL,
|
||||
defineAction,
|
||||
formDataToObject,
|
||||
getActionContext,
|
||||
serializeActionResult
|
||||
};
|
||||
64
node_modules/astro/dist/actions/runtime/types.d.ts
generated
vendored
Normal file
64
node_modules/astro/dist/actions/runtime/types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
import type * as z from 'zod/v4/core';
|
||||
import type { APIContext } from '../../types/public/index.js';
|
||||
import type { ActionError, codeToStatusMap } from './client.js';
|
||||
export type ActionErrorCode = keyof typeof codeToStatusMap;
|
||||
export type ActionAccept = 'form' | 'json';
|
||||
export type ActionHandler<TInputSchema, TOutput> = TInputSchema extends z.$ZodType ? (input: z.infer<TInputSchema>, context: ActionAPIContext) => MaybePromise<TOutput> : (input: any, context: ActionAPIContext) => MaybePromise<TOutput>;
|
||||
export type ActionReturnType<T extends ActionHandler<any, any>> = Awaited<ReturnType<T>>;
|
||||
type InferKey = '__internalInfer';
|
||||
/**
|
||||
* Infers the type of an action's input based on its Zod schema
|
||||
*
|
||||
* @see https://docs.astro.build/en/reference/modules/astro-actions/#actioninputschema
|
||||
*/
|
||||
export type ActionInputSchema<T extends ActionClient<any, any, any>> = T extends {
|
||||
[key in InferKey]: any;
|
||||
} ? T[InferKey] : never;
|
||||
export type ActionClient<TOutput, TAccept extends ActionAccept | undefined, TInputSchema extends z.$ZodType | undefined> = TInputSchema extends z.$ZodType ? ((input: TAccept extends 'form' ? FormData : z.input<TInputSchema>) => Promise<SafeResult<z.input<TInputSchema> extends ErrorInferenceObject ? z.input<TInputSchema> : ErrorInferenceObject, Awaited<TOutput>>>) & {
|
||||
queryString: string;
|
||||
orThrow: (input: TAccept extends 'form' ? FormData : z.input<TInputSchema>) => Promise<Awaited<TOutput>>;
|
||||
} & {
|
||||
[key in InferKey]: TInputSchema;
|
||||
} : ((input?: any) => Promise<SafeResult<never, Awaited<TOutput>>>) & {
|
||||
orThrow: (input?: any) => Promise<Awaited<TOutput>>;
|
||||
};
|
||||
export type SafeResult<TInput extends ErrorInferenceObject, TOutput> = {
|
||||
data: TOutput;
|
||||
error: undefined;
|
||||
} | {
|
||||
data: undefined;
|
||||
error: ActionError<TInput>;
|
||||
};
|
||||
export type SerializedActionResult = {
|
||||
type: 'data';
|
||||
contentType: 'application/json+devalue';
|
||||
status: 200;
|
||||
body: string;
|
||||
} | {
|
||||
type: 'error';
|
||||
contentType: 'application/json';
|
||||
status: number;
|
||||
body: string;
|
||||
} | {
|
||||
type: 'empty';
|
||||
status: 204;
|
||||
};
|
||||
export interface ActionsLocals {
|
||||
_actionPayload: {
|
||||
actionResult: SerializedActionResult;
|
||||
actionName: string;
|
||||
};
|
||||
}
|
||||
export type ActionAPIContext = Pick<APIContext, 'request' | 'url' | 'isPrerendered' | 'locals' | 'clientAddress' | 'cookies' | 'currentLocale' | 'generator' | 'routePattern' | 'site' | 'params' | 'preferredLocale' | 'preferredLocaleList' | 'originPathname' | 'session' | 'cache' | 'csp'>;
|
||||
export type MaybePromise<T> = T | Promise<T>;
|
||||
/**
|
||||
* Used to preserve the input schema type in the error object.
|
||||
* This allows for type inference on the `fields` property
|
||||
* when type narrowed to an `ActionInputError`.
|
||||
*
|
||||
* Example: Action has an input schema of `{ name: z.string() }`.
|
||||
* When calling the action and checking `isInputError(result.error)`,
|
||||
* `result.error.fields` will be typed with the `name` field.
|
||||
*/
|
||||
export type ErrorInferenceObject = Record<string, any>;
|
||||
export {};
|
||||
0
node_modules/astro/dist/actions/runtime/types.js
generated
vendored
Normal file
0
node_modules/astro/dist/actions/runtime/types.js
generated
vendored
Normal file
10
node_modules/astro/dist/actions/utils.d.ts
generated
vendored
Normal file
10
node_modules/astro/dist/actions/utils.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import type fsMod from 'node:fs';
|
||||
import type { APIContext } from '../types/public/context.js';
|
||||
import type { ActionAPIContext, ActionsLocals } from './runtime/types.js';
|
||||
export declare function hasActionPayload(locals: APIContext['locals']): locals is ActionsLocals;
|
||||
export declare function createGetActionResult(locals: APIContext['locals']): APIContext['getActionResult'];
|
||||
export declare function createCallAction(context: ActionAPIContext): APIContext['callAction'];
|
||||
/**
|
||||
* Check whether the Actions config file is present.
|
||||
*/
|
||||
export declare function isActionsFilePresent(fs: typeof fsMod, srcDir: URL): Promise<string | false>;
|
||||
65
node_modules/astro/dist/actions/utils.js
generated
vendored
Normal file
65
node_modules/astro/dist/actions/utils.js
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
import * as eslexer from "es-module-lexer";
|
||||
import { deserializeActionResult, getActionQueryString } from "./runtime/client.js";
|
||||
import { ACTION_API_CONTEXT_SYMBOL } from "./runtime/server.js";
|
||||
function hasActionPayload(locals) {
|
||||
return "_actionPayload" in locals;
|
||||
}
|
||||
function createGetActionResult(locals) {
|
||||
return (actionFn) => {
|
||||
if (!hasActionPayload(locals) || actionFn.toString() !== getActionQueryString(locals._actionPayload.actionName)) {
|
||||
return void 0;
|
||||
}
|
||||
return deserializeActionResult(locals._actionPayload.actionResult);
|
||||
};
|
||||
}
|
||||
function createCallAction(context) {
|
||||
return (baseAction, input) => {
|
||||
Reflect.set(context, ACTION_API_CONTEXT_SYMBOL, true);
|
||||
const action = baseAction.bind(context);
|
||||
return action(input);
|
||||
};
|
||||
}
|
||||
let didInitLexer = false;
|
||||
async function isActionsFilePresent(fs, srcDir) {
|
||||
if (!didInitLexer) await eslexer.init;
|
||||
const actionsFile = search(fs, srcDir);
|
||||
if (!actionsFile) return false;
|
||||
let contents;
|
||||
try {
|
||||
contents = fs.readFileSync(actionsFile.url, "utf-8");
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
const [, exports] = eslexer.parse(contents, actionsFile.url.pathname);
|
||||
for (const exp of exports) {
|
||||
if (exp.n === "server") {
|
||||
return actionsFile.filename;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function search(fs, srcDir) {
|
||||
const filenames = [
|
||||
"actions.mjs",
|
||||
"actions.js",
|
||||
"actions.mts",
|
||||
"actions.ts",
|
||||
"actions/index.mjs",
|
||||
"actions/index.js",
|
||||
"actions/index.mts",
|
||||
"actions/index.ts"
|
||||
];
|
||||
for (const filename of filenames) {
|
||||
const url = new URL(filename, srcDir);
|
||||
if (fs.existsSync(url)) {
|
||||
return { filename, url };
|
||||
}
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
export {
|
||||
createCallAction,
|
||||
createGetActionResult,
|
||||
hasActionPayload,
|
||||
isActionsFilePresent
|
||||
};
|
||||
15
node_modules/astro/dist/actions/vite-plugin-actions.d.ts
generated
vendored
Normal file
15
node_modules/astro/dist/actions/vite-plugin-actions.d.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import type fsMod from 'node:fs';
|
||||
import type { Plugin as VitePlugin } from 'vite';
|
||||
import type { BuildInternals } from '../core/build/internal.js';
|
||||
import type { StaticBuildOptions } from '../core/build/types.js';
|
||||
import type { AstroSettings } from '../types/astro.js';
|
||||
/**
|
||||
* This plugin is used to retrieve the final entry point of the bundled actions.ts file
|
||||
* @param opts
|
||||
* @param internals
|
||||
*/
|
||||
export declare function vitePluginActionsBuild(opts: StaticBuildOptions, internals: BuildInternals): VitePlugin;
|
||||
export declare function vitePluginActions({ fs, settings, }: {
|
||||
fs: typeof fsMod;
|
||||
settings: AstroSettings;
|
||||
}): VitePlugin;
|
||||
113
node_modules/astro/dist/actions/vite-plugin-actions.js
generated
vendored
Normal file
113
node_modules/astro/dist/actions/vite-plugin-actions.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
import { shouldAppendForwardSlash } from "../core/build/util.js";
|
||||
import { getServerOutputDirectory } from "../prerender/utils.js";
|
||||
import {
|
||||
ACTIONS_ENTRYPOINT_VIRTUAL_MODULE_ID,
|
||||
ACTIONS_RESOLVED_ENTRYPOINT_VIRTUAL_MODULE_ID,
|
||||
OPTIONS_VIRTUAL_MODULE_ID,
|
||||
RESOLVED_NOOP_ENTRYPOINT_VIRTUAL_MODULE_ID,
|
||||
RESOLVED_OPTIONS_VIRTUAL_MODULE_ID,
|
||||
RESOLVED_VIRTUAL_MODULE_ID,
|
||||
VIRTUAL_MODULE_ID
|
||||
} from "./consts.js";
|
||||
import { isActionsFilePresent } from "./utils.js";
|
||||
import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../core/constants.js";
|
||||
function vitePluginActionsBuild(opts, internals) {
|
||||
return {
|
||||
name: "@astro/plugin-actions-build",
|
||||
applyToEnvironment(environment) {
|
||||
return environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.ssr || environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.prerender || environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.astro;
|
||||
},
|
||||
writeBundle(_, bundle) {
|
||||
for (const [chunkName, chunk] of Object.entries(bundle)) {
|
||||
if (chunk.type !== "asset" && chunk.facadeModuleId === ACTIONS_RESOLVED_ENTRYPOINT_VIRTUAL_MODULE_ID) {
|
||||
const outputDirectory = getServerOutputDirectory(opts.settings);
|
||||
internals.astroActionsEntryPoint = new URL(chunkName, outputDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function vitePluginActions({
|
||||
fs,
|
||||
settings
|
||||
}) {
|
||||
let resolvedActionsId;
|
||||
return {
|
||||
name: VIRTUAL_MODULE_ID,
|
||||
enforce: "pre",
|
||||
resolveId: {
|
||||
filter: {
|
||||
id: new RegExp(
|
||||
`^(${VIRTUAL_MODULE_ID}|${OPTIONS_VIRTUAL_MODULE_ID}|${ACTIONS_ENTRYPOINT_VIRTUAL_MODULE_ID})$`
|
||||
)
|
||||
},
|
||||
async handler(id) {
|
||||
if (id === VIRTUAL_MODULE_ID) {
|
||||
return RESOLVED_VIRTUAL_MODULE_ID;
|
||||
}
|
||||
if (id === OPTIONS_VIRTUAL_MODULE_ID) {
|
||||
return RESOLVED_OPTIONS_VIRTUAL_MODULE_ID;
|
||||
}
|
||||
if (id === ACTIONS_ENTRYPOINT_VIRTUAL_MODULE_ID) {
|
||||
const resolvedModule = await this.resolve(
|
||||
`${decodeURI(new URL("actions", settings.config.srcDir).pathname)}`
|
||||
);
|
||||
if (!resolvedModule) {
|
||||
return RESOLVED_NOOP_ENTRYPOINT_VIRTUAL_MODULE_ID;
|
||||
}
|
||||
resolvedActionsId = resolvedModule.id;
|
||||
return ACTIONS_RESOLVED_ENTRYPOINT_VIRTUAL_MODULE_ID;
|
||||
}
|
||||
}
|
||||
},
|
||||
async configureServer(server) {
|
||||
const filePresentOnStartup = await isActionsFilePresent(fs, settings.config.srcDir);
|
||||
async function watcherCallback() {
|
||||
const filePresent = await isActionsFilePresent(fs, settings.config.srcDir);
|
||||
if (filePresentOnStartup !== filePresent) {
|
||||
server.restart();
|
||||
}
|
||||
}
|
||||
server.watcher.on("add", watcherCallback);
|
||||
server.watcher.on("change", watcherCallback);
|
||||
},
|
||||
load: {
|
||||
filter: {
|
||||
id: new RegExp(
|
||||
`^(${RESOLVED_VIRTUAL_MODULE_ID}|${RESOLVED_NOOP_ENTRYPOINT_VIRTUAL_MODULE_ID}|${ACTIONS_RESOLVED_ENTRYPOINT_VIRTUAL_MODULE_ID}|${RESOLVED_OPTIONS_VIRTUAL_MODULE_ID})$`
|
||||
)
|
||||
},
|
||||
async handler(id) {
|
||||
if (id === RESOLVED_VIRTUAL_MODULE_ID) {
|
||||
if (this.environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.client) {
|
||||
return {
|
||||
code: `export * from 'astro/actions/runtime/entrypoints/client.js';`
|
||||
};
|
||||
}
|
||||
return {
|
||||
code: `export * from 'astro/actions/runtime/entrypoints/server.js';`
|
||||
};
|
||||
}
|
||||
if (id === RESOLVED_NOOP_ENTRYPOINT_VIRTUAL_MODULE_ID) {
|
||||
return { code: "export const server = {}" };
|
||||
}
|
||||
if (id === ACTIONS_RESOLVED_ENTRYPOINT_VIRTUAL_MODULE_ID) {
|
||||
return { code: `export { server } from ${JSON.stringify(resolvedActionsId)};` };
|
||||
}
|
||||
if (id === RESOLVED_OPTIONS_VIRTUAL_MODULE_ID) {
|
||||
return {
|
||||
code: `
|
||||
export const shouldAppendTrailingSlash = ${JSON.stringify(
|
||||
shouldAppendForwardSlash(settings.config.trailingSlash, settings.config.build.format)
|
||||
)};
|
||||
`
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
vitePluginActions,
|
||||
vitePluginActionsBuild
|
||||
};
|
||||
Reference in New Issue
Block a user