full site update
This commit is contained in:
8
node_modules/astro/dist/actions/consts.d.ts
generated
vendored
8
node_modules/astro/dist/actions/consts.d.ts
generated
vendored
@@ -1,11 +1,11 @@
|
||||
export declare const VIRTUAL_MODULE_ID = "astro:actions";
|
||||
export declare const RESOLVED_VIRTUAL_MODULE_ID: string;
|
||||
export declare const ACTIONS_TYPES_FILE = "astro/actions.d.ts";
|
||||
export declare const VIRTUAL_INTERNAL_MODULE_ID = "astro:internal-actions";
|
||||
export declare const RESOLVED_VIRTUAL_INTERNAL_MODULE_ID = "\0astro:internal-actions";
|
||||
export declare const ACTIONS_TYPES_FILE = "actions.d.ts";
|
||||
export declare const ASTRO_ACTIONS_INTERNAL_MODULE_ID = "astro-internal:actions";
|
||||
export declare const RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID: string;
|
||||
export declare const NOOP_ACTIONS = "\0noop-actions";
|
||||
export declare const ACTION_QUERY_PARAMS: {
|
||||
actionName: string;
|
||||
actionPayload: string;
|
||||
actionRedirect: string;
|
||||
};
|
||||
export declare const ACTION_RPC_ROUTE_PATTERN = "/_actions/[...path]";
|
||||
|
17
node_modules/astro/dist/actions/consts.js
generated
vendored
17
node_modules/astro/dist/actions/consts.js
generated
vendored
@@ -1,20 +1,21 @@
|
||||
const VIRTUAL_MODULE_ID = "astro:actions";
|
||||
const RESOLVED_VIRTUAL_MODULE_ID = "\0" + VIRTUAL_MODULE_ID;
|
||||
const ACTIONS_TYPES_FILE = "astro/actions.d.ts";
|
||||
const VIRTUAL_INTERNAL_MODULE_ID = "astro:internal-actions";
|
||||
const RESOLVED_VIRTUAL_INTERNAL_MODULE_ID = "\0astro:internal-actions";
|
||||
const ACTIONS_TYPES_FILE = "actions.d.ts";
|
||||
const ASTRO_ACTIONS_INTERNAL_MODULE_ID = "astro-internal:actions";
|
||||
const RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID = "\0" + ASTRO_ACTIONS_INTERNAL_MODULE_ID;
|
||||
const NOOP_ACTIONS = "\0noop-actions";
|
||||
const ACTION_QUERY_PARAMS = {
|
||||
actionName: "_astroAction",
|
||||
actionPayload: "_astroActionPayload",
|
||||
actionRedirect: "_astroActionRedirect"
|
||||
actionName: "_action",
|
||||
actionPayload: "_astroActionPayload"
|
||||
};
|
||||
const ACTION_RPC_ROUTE_PATTERN = "/_actions/[...path]";
|
||||
export {
|
||||
ACTIONS_TYPES_FILE,
|
||||
ACTION_QUERY_PARAMS,
|
||||
ACTION_RPC_ROUTE_PATTERN,
|
||||
ASTRO_ACTIONS_INTERNAL_MODULE_ID,
|
||||
NOOP_ACTIONS,
|
||||
RESOLVED_VIRTUAL_INTERNAL_MODULE_ID,
|
||||
RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID,
|
||||
RESOLVED_VIRTUAL_MODULE_ID,
|
||||
VIRTUAL_INTERNAL_MODULE_ID,
|
||||
VIRTUAL_MODULE_ID
|
||||
};
|
||||
|
6
node_modules/astro/dist/actions/integration.d.ts
generated
vendored
6
node_modules/astro/dist/actions/integration.d.ts
generated
vendored
@@ -1,8 +1,10 @@
|
||||
import type { AstroIntegration, AstroSettings } from '../@types/astro.js';
|
||||
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, }: {
|
||||
export default function astroIntegrationActionsRouteHandler({ settings, filename, }: {
|
||||
settings: AstroSettings;
|
||||
filename: string;
|
||||
}): AstroIntegration;
|
||||
|
26
node_modules/astro/dist/actions/integration.js
generated
vendored
26
node_modules/astro/dist/actions/integration.js
generated
vendored
@@ -1,32 +1,30 @@
|
||||
import { ActionsWithoutServerOutputError } from "../core/errors/errors-data.js";
|
||||
import { AstroError } from "../core/errors/errors.js";
|
||||
import { isServerLikeOutput, viteID } from "../core/util.js";
|
||||
import { ACTIONS_TYPES_FILE, VIRTUAL_MODULE_ID } from "./consts.js";
|
||||
import { ActionsWithoutServerOutputError } from "../core/errors/errors-data.js";
|
||||
import { viteID } from "../core/util.js";
|
||||
import { ACTION_RPC_ROUTE_PATTERN, ACTIONS_TYPES_FILE, VIRTUAL_MODULE_ID } from "./consts.js";
|
||||
function astroIntegrationActionsRouteHandler({
|
||||
settings
|
||||
settings,
|
||||
filename
|
||||
}) {
|
||||
return {
|
||||
name: VIRTUAL_MODULE_ID,
|
||||
hooks: {
|
||||
async "astro:config:setup"(params) {
|
||||
params.injectRoute({
|
||||
pattern: "/_actions/[...path]",
|
||||
async "astro:config:setup"() {
|
||||
settings.injectedRoutes.push({
|
||||
pattern: ACTION_RPC_ROUTE_PATTERN,
|
||||
entrypoint: "astro/actions/runtime/route.js",
|
||||
prerender: false
|
||||
});
|
||||
params.addMiddleware({
|
||||
entrypoint: "astro/actions/runtime/middleware.js",
|
||||
order: "post"
|
||||
prerender: false,
|
||||
origin: "internal"
|
||||
});
|
||||
},
|
||||
"astro:config:done": async (params) => {
|
||||
if (!isServerLikeOutput(params.config)) {
|
||||
if (params.buildOutput === "static") {
|
||||
const error = new AstroError(ActionsWithoutServerOutputError);
|
||||
error.stack = void 0;
|
||||
throw error;
|
||||
}
|
||||
const stringifiedActionsImport = JSON.stringify(
|
||||
viteID(new URL("./actions", params.config.srcDir))
|
||||
viteID(new URL(`./${filename}`, params.config.srcDir))
|
||||
);
|
||||
settings.injectedTypes.push({
|
||||
filename: ACTIONS_TYPES_FILE,
|
||||
|
8
node_modules/astro/dist/actions/loadActions.d.ts
generated
vendored
Normal file
8
node_modules/astro/dist/actions/loadActions.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { SSRActions } from '../core/app/types.js';
|
||||
import type { ModuleLoader } from '../core/module-loader/index.js';
|
||||
/**
|
||||
* It accepts a module loader and the astro settings, and it attempts to load the middlewares defined in the configuration.
|
||||
*
|
||||
* If not middlewares were not set, the function returns an empty array.
|
||||
*/
|
||||
export declare function loadActions(moduleLoader: ModuleLoader): Promise<SSRActions>;
|
13
node_modules/astro/dist/actions/loadActions.js
generated
vendored
Normal file
13
node_modules/astro/dist/actions/loadActions.js
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import { ActionsCantBeLoaded } from "../core/errors/errors-data.js";
|
||||
import { AstroError } from "../core/errors/index.js";
|
||||
import { ASTRO_ACTIONS_INTERNAL_MODULE_ID } from "./consts.js";
|
||||
async function loadActions(moduleLoader) {
|
||||
try {
|
||||
return await moduleLoader.import(ASTRO_ACTIONS_INTERNAL_MODULE_ID);
|
||||
} catch (error) {
|
||||
throw new AstroError(ActionsCantBeLoaded, { cause: error });
|
||||
}
|
||||
}
|
||||
export {
|
||||
loadActions
|
||||
};
|
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
|
||||
};
|
10
node_modules/astro/dist/actions/plugins.d.ts
generated
vendored
10
node_modules/astro/dist/actions/plugins.d.ts
generated
vendored
@@ -1,6 +1,8 @@
|
||||
import type fsMod from 'node:fs';
|
||||
import type { Plugin as VitePlugin } from 'vite';
|
||||
import type { AstroSettings } from '../@types/astro.js';
|
||||
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 responsible to load the known file `actions/index.js` / `actions.js`
|
||||
* If the file doesn't exist, it returns an empty object.
|
||||
@@ -9,6 +11,12 @@ import type { AstroSettings } from '../@types/astro.js';
|
||||
export declare function vitePluginUserActions({ settings }: {
|
||||
settings: AstroSettings;
|
||||
}): VitePlugin;
|
||||
/**
|
||||
* 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;
|
||||
|
38
node_modules/astro/dist/actions/plugins.js
generated
vendored
38
node_modules/astro/dist/actions/plugins.js
generated
vendored
@@ -1,8 +1,11 @@
|
||||
import { addRollupInput } from "../core/build/add-rollup-input.js";
|
||||
import { shouldAppendForwardSlash } from "../core/build/util.js";
|
||||
import { getServerOutputDirectory } from "../prerender/utils.js";
|
||||
import {
|
||||
ASTRO_ACTIONS_INTERNAL_MODULE_ID,
|
||||
NOOP_ACTIONS,
|
||||
RESOLVED_VIRTUAL_INTERNAL_MODULE_ID,
|
||||
RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID,
|
||||
RESOLVED_VIRTUAL_MODULE_ID,
|
||||
VIRTUAL_INTERNAL_MODULE_ID,
|
||||
VIRTUAL_MODULE_ID
|
||||
} from "./consts.js";
|
||||
import { isActionsFilePresent } from "./utils.js";
|
||||
@@ -14,7 +17,7 @@ function vitePluginUserActions({ settings }) {
|
||||
if (id === NOOP_ACTIONS) {
|
||||
return NOOP_ACTIONS;
|
||||
}
|
||||
if (id === VIRTUAL_INTERNAL_MODULE_ID) {
|
||||
if (id === ASTRO_ACTIONS_INTERNAL_MODULE_ID) {
|
||||
const resolvedModule = await this.resolve(
|
||||
`${decodeURI(new URL("actions", settings.config.srcDir).pathname)}`
|
||||
);
|
||||
@@ -22,18 +25,34 @@ function vitePluginUserActions({ settings }) {
|
||||
return NOOP_ACTIONS;
|
||||
}
|
||||
resolvedActionsId = resolvedModule.id;
|
||||
return RESOLVED_VIRTUAL_INTERNAL_MODULE_ID;
|
||||
return RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID;
|
||||
}
|
||||
},
|
||||
load(id) {
|
||||
if (id === NOOP_ACTIONS) {
|
||||
return "export const server = {}";
|
||||
} else if (id === RESOLVED_VIRTUAL_INTERNAL_MODULE_ID) {
|
||||
} else if (id === RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID) {
|
||||
return `export { server } from '${resolvedActionsId}';`;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function vitePluginActionsBuild(opts, internals) {
|
||||
return {
|
||||
name: "@astro/plugin-actions-build",
|
||||
options(options) {
|
||||
return addRollupInput(options, [ASTRO_ACTIONS_INTERNAL_MODULE_ID]);
|
||||
},
|
||||
writeBundle(_, bundle) {
|
||||
for (const [chunkName, chunk] of Object.entries(bundle)) {
|
||||
if (chunk.type !== "asset" && chunk.facadeModuleId === RESOLVED_ASTRO_ACTIONS_INTERNAL_MODULE_ID) {
|
||||
const outputDirectory = getServerOutputDirectory(opts.settings);
|
||||
internals.astroActionsEntryPoint = new URL(chunkName, outputDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function vitePluginActions({
|
||||
fs,
|
||||
settings
|
||||
@@ -70,11 +89,18 @@ export * from 'astro/actions/runtime/virtual/server.js';`;
|
||||
code += `
|
||||
export * from 'astro/actions/runtime/virtual/client.js';`;
|
||||
}
|
||||
return code;
|
||||
code = code.replace(
|
||||
"'/** @TRAILING_SLASH@ **/'",
|
||||
JSON.stringify(
|
||||
shouldAppendForwardSlash(settings.config.trailingSlash, settings.config.build.format)
|
||||
)
|
||||
);
|
||||
return { code };
|
||||
}
|
||||
};
|
||||
}
|
||||
export {
|
||||
vitePluginActions,
|
||||
vitePluginActionsBuild,
|
||||
vitePluginUserActions
|
||||
};
|
||||
|
9
node_modules/astro/dist/actions/runtime/middleware.d.ts
generated
vendored
9
node_modules/astro/dist/actions/runtime/middleware.d.ts
generated
vendored
@@ -1,9 +0,0 @@
|
||||
import { type SerializedActionResult } from './virtual/shared.js';
|
||||
export type ActionPayload = {
|
||||
actionResult: SerializedActionResult;
|
||||
actionName: string;
|
||||
};
|
||||
export type Locals = {
|
||||
_actionPayload: ActionPayload;
|
||||
};
|
||||
export declare const onRequest: import("../../@types/astro.js").MiddlewareHandler;
|
110
node_modules/astro/dist/actions/runtime/middleware.js
generated
vendored
110
node_modules/astro/dist/actions/runtime/middleware.js
generated
vendored
@@ -1,110 +0,0 @@
|
||||
import { yellow } from "kleur/colors";
|
||||
import { defineMiddleware } from "../../core/middleware/index.js";
|
||||
import { getOriginPathname } from "../../core/routing/rewrite.js";
|
||||
import { ACTION_QUERY_PARAMS } from "../consts.js";
|
||||
import { ACTION_API_CONTEXT_SYMBOL, formContentTypes, hasContentType } from "./utils.js";
|
||||
import { getAction } from "./virtual/get-action.js";
|
||||
import {
|
||||
serializeActionResult
|
||||
} from "./virtual/shared.js";
|
||||
const onRequest = defineMiddleware(async (context, next) => {
|
||||
if (context._isPrerendered) {
|
||||
if (context.request.method === "POST") {
|
||||
console.warn(
|
||||
yellow("[astro:actions]"),
|
||||
"POST requests should not be sent to prerendered pages. If you're using Actions, disable prerendering with `export const prerender = false`."
|
||||
);
|
||||
}
|
||||
return next();
|
||||
}
|
||||
const locals = context.locals;
|
||||
if (locals._actionPayload) return next();
|
||||
const actionPayload = context.cookies.get(ACTION_QUERY_PARAMS.actionPayload)?.json();
|
||||
if (actionPayload) {
|
||||
if (!isActionPayload(actionPayload)) {
|
||||
throw new Error("Internal: Invalid action payload in cookie.");
|
||||
}
|
||||
return renderResult({ context, next, ...actionPayload });
|
||||
}
|
||||
const actionName = context.url.searchParams.get(ACTION_QUERY_PARAMS.actionName);
|
||||
if (context.request.method === "POST" && actionName) {
|
||||
return handlePost({ context, next, actionName });
|
||||
}
|
||||
return next();
|
||||
});
|
||||
async function renderResult({
|
||||
context,
|
||||
next,
|
||||
actionResult,
|
||||
actionName
|
||||
}) {
|
||||
const locals = context.locals;
|
||||
locals._actionPayload = { actionResult, actionName };
|
||||
const response = await next();
|
||||
context.cookies.delete(ACTION_QUERY_PARAMS.actionPayload);
|
||||
if (actionResult.type === "error") {
|
||||
return new Response(response.body, {
|
||||
status: actionResult.status,
|
||||
statusText: actionResult.type,
|
||||
headers: response.headers
|
||||
});
|
||||
}
|
||||
return response;
|
||||
}
|
||||
async function handlePost({
|
||||
context,
|
||||
next,
|
||||
actionName
|
||||
}) {
|
||||
const { request } = context;
|
||||
const baseAction = await getAction(actionName);
|
||||
const contentType = request.headers.get("content-type");
|
||||
let formData;
|
||||
if (contentType && hasContentType(contentType, formContentTypes)) {
|
||||
formData = await request.clone().formData();
|
||||
}
|
||||
const { getActionResult, callAction, props, redirect, ...actionAPIContext } = context;
|
||||
Reflect.set(actionAPIContext, ACTION_API_CONTEXT_SYMBOL, true);
|
||||
const action = baseAction.bind(actionAPIContext);
|
||||
const actionResult = await action(formData);
|
||||
if (context.url.searchParams.get(ACTION_QUERY_PARAMS.actionRedirect) === "false") {
|
||||
return renderResult({
|
||||
context,
|
||||
next,
|
||||
actionName,
|
||||
actionResult: serializeActionResult(actionResult)
|
||||
});
|
||||
}
|
||||
return redirectWithResult({ context, actionName, actionResult });
|
||||
}
|
||||
async function redirectWithResult({
|
||||
context,
|
||||
actionName,
|
||||
actionResult
|
||||
}) {
|
||||
context.cookies.set(ACTION_QUERY_PARAMS.actionPayload, {
|
||||
actionName,
|
||||
actionResult: serializeActionResult(actionResult)
|
||||
});
|
||||
if (actionResult.error) {
|
||||
const referer2 = context.request.headers.get("Referer");
|
||||
if (!referer2) {
|
||||
throw new Error("Internal: Referer unexpectedly missing from Action POST request.");
|
||||
}
|
||||
return context.redirect(referer2);
|
||||
}
|
||||
const referer = getOriginPathname(context.request);
|
||||
if (referer) {
|
||||
return context.redirect(referer);
|
||||
}
|
||||
return context.redirect(context.url.pathname);
|
||||
}
|
||||
function isActionPayload(json) {
|
||||
if (typeof json !== "object" || json == null) return false;
|
||||
if (!("actionResult" in json) || typeof json.actionResult !== "object") return false;
|
||||
if (!("actionName" in json) || typeof json.actionName !== "string") return false;
|
||||
return true;
|
||||
}
|
||||
export {
|
||||
onRequest
|
||||
};
|
2
node_modules/astro/dist/actions/runtime/route.d.ts
generated
vendored
2
node_modules/astro/dist/actions/runtime/route.d.ts
generated
vendored
@@ -1,2 +1,2 @@
|
||||
import type { APIRoute } from '../../@types/astro.js';
|
||||
import type { APIRoute } from '../../types/public/common.js';
|
||||
export declare const POST: APIRoute;
|
||||
|
32
node_modules/astro/dist/actions/runtime/route.js
generated
vendored
32
node_modules/astro/dist/actions/runtime/route.js
generated
vendored
@@ -1,32 +1,10 @@
|
||||
import { ACTION_API_CONTEXT_SYMBOL, formContentTypes, hasContentType } from "./utils.js";
|
||||
import { getAction } from "./virtual/get-action.js";
|
||||
import { serializeActionResult } from "./virtual/shared.js";
|
||||
import { getActionContext } from "./virtual/server.js";
|
||||
const POST = async (context) => {
|
||||
const { request, url } = context;
|
||||
let baseAction;
|
||||
try {
|
||||
baseAction = await getAction(url.pathname);
|
||||
} catch (e) {
|
||||
if (import.meta.env.DEV) throw e;
|
||||
console.error(e);
|
||||
return new Response(e instanceof Error ? e.message : null, { status: 404 });
|
||||
const { action, serializeActionResult } = getActionContext(context);
|
||||
if (action?.calledFrom !== "rpc") {
|
||||
return new Response("Not found", { status: 404 });
|
||||
}
|
||||
const contentType = request.headers.get("Content-Type");
|
||||
const contentLength = request.headers.get("Content-Length");
|
||||
let args;
|
||||
if (!contentType || contentLength === "0") {
|
||||
args = void 0;
|
||||
} else if (contentType && hasContentType(contentType, formContentTypes)) {
|
||||
args = await request.clone().formData();
|
||||
} else if (contentType && hasContentType(contentType, ["application/json"])) {
|
||||
args = await request.clone().json();
|
||||
} else {
|
||||
return new Response(null, { status: 415 });
|
||||
}
|
||||
const { getActionResult, callAction, props, redirect, ...actionAPIContext } = context;
|
||||
Reflect.set(actionAPIContext, ACTION_API_CONTEXT_SYMBOL, true);
|
||||
const action = baseAction.bind(actionAPIContext);
|
||||
const result = await action(args);
|
||||
const result = await action.handler();
|
||||
const serialized = serializeActionResult(result);
|
||||
if (serialized.type === "empty") {
|
||||
return new Response(null, {
|
||||
|
18
node_modules/astro/dist/actions/runtime/utils.d.ts
generated
vendored
18
node_modules/astro/dist/actions/runtime/utils.d.ts
generated
vendored
@@ -1,8 +1,22 @@
|
||||
import type { APIContext } from '../../@types/astro.js';
|
||||
import type { APIContext, AstroSharedContext } from '../../types/public/context.js';
|
||||
import type { SerializedActionResult } from './virtual/shared.js';
|
||||
export type ActionPayload = {
|
||||
actionResult: SerializedActionResult;
|
||||
actionName: string;
|
||||
};
|
||||
export type Locals = {
|
||||
_actionPayload: ActionPayload;
|
||||
};
|
||||
export declare const ACTION_API_CONTEXT_SYMBOL: unique symbol;
|
||||
export declare const formContentTypes: string[];
|
||||
export declare function hasContentType(contentType: string, expected: string[]): boolean;
|
||||
export type ActionAPIContext = Omit<APIContext, 'getActionResult' | 'callAction' | 'props' | 'redirect'>;
|
||||
export type ActionAPIContext = Pick<APIContext, 'rewrite' | 'request' | 'url' | 'isPrerendered' | 'locals' | 'clientAddress' | 'cookies' | 'currentLocale' | 'generator' | 'routePattern' | 'site' | 'params' | 'preferredLocale' | 'preferredLocaleList' | 'originPathname' | 'session' | 'insertDirective' | 'insertScriptResource' | 'insertStyleResource' | 'insertScriptHash' | 'insertStyleHash'> & {
|
||||
/**
|
||||
* @deprecated
|
||||
* The use of `rewrite` in Actions is deprecated
|
||||
*/
|
||||
rewrite: AstroSharedContext['rewrite'];
|
||||
};
|
||||
export type MaybePromise<T> = T | Promise<T>;
|
||||
/**
|
||||
* Used to preserve the input schema type in the error object.
|
||||
|
1
node_modules/astro/dist/actions/runtime/virtual/client.d.ts
generated
vendored
1
node_modules/astro/dist/actions/runtime/virtual/client.d.ts
generated
vendored
@@ -1,2 +1,3 @@
|
||||
export * from './shared.js';
|
||||
export declare function defineAction(): void;
|
||||
export declare function getActionContext(): void;
|
||||
|
6
node_modules/astro/dist/actions/runtime/virtual/client.js
generated
vendored
6
node_modules/astro/dist/actions/runtime/virtual/client.js
generated
vendored
@@ -2,6 +2,10 @@ export * from "./shared.js";
|
||||
function defineAction() {
|
||||
throw new Error("[astro:action] `defineAction()` unexpectedly used on the client.");
|
||||
}
|
||||
function getActionContext() {
|
||||
throw new Error("[astro:action] `getActionContext()` unexpectedly used on the client.");
|
||||
}
|
||||
export {
|
||||
defineAction
|
||||
defineAction,
|
||||
getActionContext
|
||||
};
|
||||
|
8
node_modules/astro/dist/actions/runtime/virtual/get-action.d.ts
generated
vendored
8
node_modules/astro/dist/actions/runtime/virtual/get-action.d.ts
generated
vendored
@@ -1,8 +0,0 @@
|
||||
import type { ZodType } from 'zod';
|
||||
import type { ActionAccept, ActionClient } from './server.js';
|
||||
/**
|
||||
* Get server-side action based on the route path.
|
||||
* Imports from the virtual module `astro:internal-actions`, which maps to
|
||||
* the user's `src/actions/index.ts` file at build-time.
|
||||
*/
|
||||
export declare function getAction(path: string): Promise<ActionClient<unknown, ActionAccept, ZodType>>;
|
29
node_modules/astro/dist/actions/runtime/virtual/get-action.js
generated
vendored
29
node_modules/astro/dist/actions/runtime/virtual/get-action.js
generated
vendored
@@ -1,29 +0,0 @@
|
||||
import { ActionNotFoundError } from "../../../core/errors/errors-data.js";
|
||||
import { AstroError } from "../../../core/errors/errors.js";
|
||||
async function getAction(path) {
|
||||
const pathKeys = path.replace(/^.*\/_actions\//, "").split(".").map((key) => decodeURIComponent(key));
|
||||
let { server: actionLookup } = await import("astro:internal-actions");
|
||||
if (actionLookup == null || !(typeof actionLookup === "object")) {
|
||||
throw new TypeError(
|
||||
`Expected \`server\` export in actions file to be an object. Received ${typeof actionLookup}.`
|
||||
);
|
||||
}
|
||||
for (const key of pathKeys) {
|
||||
if (!(key in actionLookup)) {
|
||||
throw new AstroError({
|
||||
...ActionNotFoundError,
|
||||
message: ActionNotFoundError.message(pathKeys.join("."))
|
||||
});
|
||||
}
|
||||
actionLookup = actionLookup[key];
|
||||
}
|
||||
if (typeof actionLookup !== "function") {
|
||||
throw new TypeError(
|
||||
`Expected handler for action ${pathKeys.join(".")} to be a function. Received ${typeof actionLookup}.`
|
||||
);
|
||||
}
|
||||
return actionLookup;
|
||||
}
|
||||
export {
|
||||
getAction
|
||||
};
|
32
node_modules/astro/dist/actions/runtime/virtual/server.d.ts
generated
vendored
32
node_modules/astro/dist/actions/runtime/virtual/server.d.ts
generated
vendored
@@ -1,6 +1,7 @@
|
||||
import { z } from 'zod';
|
||||
import type { APIContext } from '../../../types/public/index.js';
|
||||
import { type ActionAPIContext, type ErrorInferenceObject, type MaybePromise } from '../utils.js';
|
||||
import { type SafeResult } from './shared.js';
|
||||
import { deserializeActionResult, type SafeResult, type SerializedActionResult, serializeActionResult } from './shared.js';
|
||||
export * from './shared.js';
|
||||
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>;
|
||||
@@ -18,3 +19,32 @@ export declare function defineAction<TOutput, TAccept extends ActionAccept | und
|
||||
}): ActionClient<TOutput, TAccept, TInputSchema> & string;
|
||||
/** Transform form data to an object based on a Zod schema. */
|
||||
export declare function formDataToObject<T extends z.AnyZodObject>(formData: FormData, schema: T): Record<string, unknown>;
|
||||
export type 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;
|
||||
|
95
node_modules/astro/dist/actions/runtime/virtual/server.js
generated
vendored
95
node_modules/astro/dist/actions/runtime/virtual/server.js
generated
vendored
@@ -1,10 +1,24 @@
|
||||
import { z } from "zod";
|
||||
import { ActionCalledFromServerError } from "../../../core/errors/errors-data.js";
|
||||
import { shouldAppendForwardSlash } from "../../../core/build/util.js";
|
||||
import { AstroError } from "../../../core/errors/errors.js";
|
||||
import { ActionCalledFromServerError } from "../../../core/errors/errors-data.js";
|
||||
import { removeTrailingForwardSlash } from "../../../core/path.js";
|
||||
import { apiContextRoutesSymbol } from "../../../core/render-context.js";
|
||||
import { ACTION_RPC_ROUTE_PATTERN } from "../../consts.js";
|
||||
import {
|
||||
ACTION_API_CONTEXT_SYMBOL,
|
||||
formContentTypes,
|
||||
hasContentType,
|
||||
isActionAPIContext
|
||||
} from "../utils.js";
|
||||
import { ActionError, ActionInputError, callSafely } from "./shared.js";
|
||||
import {
|
||||
ACTION_QUERY_PARAMS,
|
||||
ActionError,
|
||||
ActionInputError,
|
||||
callSafely,
|
||||
deserializeActionResult,
|
||||
serializeActionResult
|
||||
} from "./shared.js";
|
||||
export * from "./shared.js";
|
||||
function defineAction({
|
||||
accept,
|
||||
@@ -122,7 +136,82 @@ function unwrapBaseObjectSchema(schema, unparsedInput) {
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
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, apiContextRoutesSymbol);
|
||||
const callerInfoName = shouldAppendForwardSlash(
|
||||
pipeline.manifest.trailingSlash,
|
||||
pipeline.manifest.buildFormat
|
||||
) ? removeTrailingForwardSlash(callerInfo.name) : callerInfo.name;
|
||||
const baseAction = await pipeline.getAction(callerInfoName);
|
||||
let input;
|
||||
try {
|
||||
input = await parseRequestBody(context.request);
|
||||
} catch (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) {
|
||||
const contentType = request.headers.get("content-type");
|
||||
const contentLength = request.headers.get("Content-Length");
|
||||
if (!contentType) return void 0;
|
||||
if (hasContentType(contentType, formContentTypes)) {
|
||||
return await request.clone().formData();
|
||||
}
|
||||
if (hasContentType(contentType, ["application/json"])) {
|
||||
return contentLength === "0" ? void 0 : await request.clone().json();
|
||||
}
|
||||
throw new TypeError("Unsupported content type");
|
||||
}
|
||||
export {
|
||||
defineAction,
|
||||
formDataToObject
|
||||
formDataToObject,
|
||||
getActionContext
|
||||
};
|
||||
|
9
node_modules/astro/dist/actions/runtime/virtual/shared.d.ts
generated
vendored
9
node_modules/astro/dist/actions/runtime/virtual/shared.d.ts
generated
vendored
@@ -1,12 +1,14 @@
|
||||
import type { z } from 'zod';
|
||||
import type { ErrorInferenceObject, MaybePromise, ActionAPIContext as _ActionAPIContext } from '../utils.js';
|
||||
import { AstroError } from '../../../core/errors/errors.js';
|
||||
import { appendForwardSlash as _appendForwardSlash } from '../../../core/path.js';
|
||||
import type { ActionAPIContext as _ActionAPIContext, ErrorInferenceObject, MaybePromise } from '../utils.js';
|
||||
export type ActionAPIContext = _ActionAPIContext;
|
||||
export declare const ACTION_QUERY_PARAMS: {
|
||||
actionName: string;
|
||||
actionPayload: string;
|
||||
actionRedirect: string;
|
||||
};
|
||||
export declare const ACTION_ERROR_CODES: readonly ["BAD_REQUEST", "UNAUTHORIZED", "FORBIDDEN", "NOT_FOUND", "TIMEOUT", "CONFLICT", "PRECONDITION_FAILED", "PAYLOAD_TOO_LARGE", "UNSUPPORTED_MEDIA_TYPE", "UNPROCESSABLE_CONTENT", "TOO_MANY_REQUESTS", "CLIENT_CLOSED_REQUEST", "INTERNAL_SERVER_ERROR"];
|
||||
export declare const appendForwardSlash: typeof _appendForwardSlash;
|
||||
export declare const ACTION_ERROR_CODES: readonly ["BAD_REQUEST", "UNAUTHORIZED", "PAYMENT_REQUIRED", "FORBIDDEN", "NOT_FOUND", "METHOD_NOT_ALLOWED", "NOT_ACCEPTABLE", "PROXY_AUTHENTICATION_REQUIRED", "REQUEST_TIMEOUT", "CONFLICT", "GONE", "LENGTH_REQUIRED", "PRECONDITION_FAILED", "CONTENT_TOO_LARGE", "URI_TOO_LONG", "UNSUPPORTED_MEDIA_TYPE", "RANGE_NOT_SATISFIABLE", "EXPECTATION_FAILED", "MISDIRECTED_REQUEST", "UNPROCESSABLE_CONTENT", "LOCKED", "FAILED_DEPENDENCY", "TOO_EARLY", "UPGRADE_REQUIRED", "PRECONDITION_REQUIRED", "TOO_MANY_REQUESTS", "REQUEST_HEADER_FIELDS_TOO_LARGE", "UNAVAILABLE_FOR_LEGAL_REASONS", "INTERNAL_SERVER_ERROR", "NOT_IMPLEMENTED", "BAD_GATEWAY", "SERVICE_UNAVAILABLE", "GATEWAY_TIMEOUT", "HTTP_VERSION_NOT_SUPPORTED", "VARIANT_ALSO_NEGOTIATES", "INSUFFICIENT_STORAGE", "LOOP_DETECTED", "NETWORK_AUTHENTICATION_REQUIRED"];
|
||||
export type ActionErrorCode = (typeof ACTION_ERROR_CODES)[number];
|
||||
export declare class ActionError<_T extends ErrorInferenceObject = ErrorInferenceObject> extends Error {
|
||||
type: string;
|
||||
@@ -55,3 +57,4 @@ export type SerializedActionResult = {
|
||||
};
|
||||
export declare function serializeActionResult(res: SafeResult<any, any>): SerializedActionResult;
|
||||
export declare function deserializeActionResult(res: SerializedActionResult): SafeResult<any, any>;
|
||||
export declare function astroCalledServerError(): AstroError;
|
||||
|
100
node_modules/astro/dist/actions/runtime/virtual/shared.js
generated
vendored
100
node_modules/astro/dist/actions/runtime/virtual/shared.js
generated
vendored
@@ -1,40 +1,95 @@
|
||||
import { parse as devalueParse, stringify as devalueStringify } from "devalue";
|
||||
import { REDIRECT_STATUS_CODES } from "../../../core/constants.js";
|
||||
import { ActionsReturnedInvalidDataError } from "../../../core/errors/errors-data.js";
|
||||
import { AstroError } from "../../../core/errors/errors.js";
|
||||
import {
|
||||
ActionCalledFromServerError,
|
||||
ActionsReturnedInvalidDataError
|
||||
} from "../../../core/errors/errors-data.js";
|
||||
import { appendForwardSlash as _appendForwardSlash } from "../../../core/path.js";
|
||||
import { ACTION_QUERY_PARAMS as _ACTION_QUERY_PARAMS } from "../../consts.js";
|
||||
const ACTION_QUERY_PARAMS = _ACTION_QUERY_PARAMS;
|
||||
const appendForwardSlash = _appendForwardSlash;
|
||||
const ACTION_ERROR_CODES = [
|
||||
"BAD_REQUEST",
|
||||
"UNAUTHORIZED",
|
||||
"PAYMENT_REQUIRED",
|
||||
"FORBIDDEN",
|
||||
"NOT_FOUND",
|
||||
"TIMEOUT",
|
||||
"METHOD_NOT_ALLOWED",
|
||||
"NOT_ACCEPTABLE",
|
||||
"PROXY_AUTHENTICATION_REQUIRED",
|
||||
"REQUEST_TIMEOUT",
|
||||
"CONFLICT",
|
||||
"GONE",
|
||||
"LENGTH_REQUIRED",
|
||||
"PRECONDITION_FAILED",
|
||||
"PAYLOAD_TOO_LARGE",
|
||||
"CONTENT_TOO_LARGE",
|
||||
"URI_TOO_LONG",
|
||||
"UNSUPPORTED_MEDIA_TYPE",
|
||||
"RANGE_NOT_SATISFIABLE",
|
||||
"EXPECTATION_FAILED",
|
||||
"MISDIRECTED_REQUEST",
|
||||
"UNPROCESSABLE_CONTENT",
|
||||
"LOCKED",
|
||||
"FAILED_DEPENDENCY",
|
||||
"TOO_EARLY",
|
||||
"UPGRADE_REQUIRED",
|
||||
"PRECONDITION_REQUIRED",
|
||||
"TOO_MANY_REQUESTS",
|
||||
"CLIENT_CLOSED_REQUEST",
|
||||
"INTERNAL_SERVER_ERROR"
|
||||
"REQUEST_HEADER_FIELDS_TOO_LARGE",
|
||||
"UNAVAILABLE_FOR_LEGAL_REASONS",
|
||||
"INTERNAL_SERVER_ERROR",
|
||||
"NOT_IMPLEMENTED",
|
||||
"BAD_GATEWAY",
|
||||
"SERVICE_UNAVAILABLE",
|
||||
"GATEWAY_TIMEOUT",
|
||||
"HTTP_VERSION_NOT_SUPPORTED",
|
||||
"VARIANT_ALSO_NEGOTIATES",
|
||||
"INSUFFICIENT_STORAGE",
|
||||
"LOOP_DETECTED",
|
||||
"NETWORK_AUTHENTICATION_REQUIRED"
|
||||
];
|
||||
const codeToStatusMap = {
|
||||
// Implemented from tRPC error code table
|
||||
// https://trpc.io/docs/server/error-handling#error-codes
|
||||
// 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,
|
||||
TIMEOUT: 405,
|
||||
METHOD_NOT_ALLOWED: 405,
|
||||
NOT_ACCEPTABLE: 406,
|
||||
PROXY_AUTHENTICATION_REQUIRED: 407,
|
||||
REQUEST_TIMEOUT: 408,
|
||||
CONFLICT: 409,
|
||||
GONE: 410,
|
||||
LENGTH_REQUIRED: 411,
|
||||
PRECONDITION_FAILED: 412,
|
||||
PAYLOAD_TOO_LARGE: 413,
|
||||
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,
|
||||
CLIENT_CLOSED_REQUEST: 499,
|
||||
INTERNAL_SERVER_ERROR: 500
|
||||
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.entries(codeToStatusMap).reduce(
|
||||
// reverse the key-value pairs
|
||||
@@ -126,14 +181,24 @@ function serializeActionResult(res) {
|
||||
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({
|
||||
...res.error,
|
||||
message: res.error.message
|
||||
})
|
||||
body: JSON.stringify(body2)
|
||||
};
|
||||
}
|
||||
if (res.data === void 0) {
|
||||
@@ -212,11 +277,16 @@ const actionResultErrorStack = /* @__PURE__ */ function actionResultErrorStackFn
|
||||
}
|
||||
};
|
||||
}();
|
||||
function astroCalledServerError() {
|
||||
return new AstroError(ActionCalledFromServerError);
|
||||
}
|
||||
export {
|
||||
ACTION_ERROR_CODES,
|
||||
ACTION_QUERY_PARAMS,
|
||||
ActionError,
|
||||
ActionInputError,
|
||||
appendForwardSlash,
|
||||
astroCalledServerError,
|
||||
callSafely,
|
||||
deserializeActionResult,
|
||||
getActionQueryString,
|
||||
|
7
node_modules/astro/dist/actions/utils.d.ts
generated
vendored
7
node_modules/astro/dist/actions/utils.d.ts
generated
vendored
@@ -1,11 +1,10 @@
|
||||
import type fsMod from 'node:fs';
|
||||
import type { APIContext } from '../@types/astro.js';
|
||||
import type { Locals } from './runtime/middleware.js';
|
||||
import { type ActionAPIContext } from './runtime/utils.js';
|
||||
import type { APIContext } from '../types/public/context.js';
|
||||
import { type ActionAPIContext, type Locals } from './runtime/utils.js';
|
||||
export declare function hasActionPayload(locals: APIContext['locals']): locals is Locals;
|
||||
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<boolean>;
|
||||
export declare function isActionsFilePresent(fs: typeof fsMod, srcDir: URL): Promise<string | false>;
|
||||
|
17
node_modules/astro/dist/actions/utils.js
generated
vendored
17
node_modules/astro/dist/actions/utils.js
generated
vendored
@@ -26,20 +26,20 @@ async function isActionsFilePresent(fs, srcDir) {
|
||||
if (!actionsFile) return false;
|
||||
let contents;
|
||||
try {
|
||||
contents = fs.readFileSync(actionsFile, "utf-8");
|
||||
contents = fs.readFileSync(actionsFile.url, "utf-8");
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
const [, exports] = eslexer.parse(contents, actionsFile.pathname);
|
||||
const [, exports] = eslexer.parse(contents, actionsFile.url.pathname);
|
||||
for (const exp of exports) {
|
||||
if (exp.n === "server") {
|
||||
return true;
|
||||
return actionsFile.filename;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function search(fs, srcDir) {
|
||||
const paths = [
|
||||
const filenames = [
|
||||
"actions.mjs",
|
||||
"actions.js",
|
||||
"actions.mts",
|
||||
@@ -48,10 +48,11 @@ function search(fs, srcDir) {
|
||||
"actions/index.js",
|
||||
"actions/index.mts",
|
||||
"actions/index.ts"
|
||||
].map((p) => new URL(p, srcDir));
|
||||
for (const file of paths) {
|
||||
if (fs.existsSync(file)) {
|
||||
return file;
|
||||
];
|
||||
for (const filename of filenames) {
|
||||
const url = new URL(filename, srcDir);
|
||||
if (fs.existsSync(url)) {
|
||||
return { filename, url };
|
||||
}
|
||||
}
|
||||
return void 0;
|
||||
|
Reference in New Issue
Block a user