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
|
||||
};
|
||||
23
node_modules/astro/dist/assets/build/generate.d.ts
generated
vendored
Normal file
23
node_modules/astro/dist/assets/build/generate.d.ts
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import type { StaticBuildOptions } from '../../core/build/types.js';
|
||||
import type { AstroLogger } from '../../core/logger/core.js';
|
||||
import type { MapValue } from '../../type-utils.js';
|
||||
import type { AstroConfig } from '../../types/public/config.js';
|
||||
import type { AssetsGlobalStaticImagesList } from '../types.js';
|
||||
type AssetEnv = {
|
||||
logger: AstroLogger;
|
||||
isSSR: boolean;
|
||||
count: {
|
||||
total: number;
|
||||
current: number;
|
||||
};
|
||||
useCache: boolean;
|
||||
assetsCacheDir: URL;
|
||||
serverRoot: URL;
|
||||
clientRoot: URL;
|
||||
imageConfig: AstroConfig['image'];
|
||||
assetsFolder: AstroConfig['build']['assets'];
|
||||
};
|
||||
export declare function prepareAssetsGenerationEnv(options: StaticBuildOptions, totalCount: number): Promise<AssetEnv>;
|
||||
export declare function generateImagesForPath(originalFilePath: string, transformsAndPath: MapValue<AssetsGlobalStaticImagesList>, env: AssetEnv): Promise<void>;
|
||||
export declare function getStaticImageList(): AssetsGlobalStaticImagesList;
|
||||
export {};
|
||||
248
node_modules/astro/dist/assets/build/generate.js
generated
vendored
Normal file
248
node_modules/astro/dist/assets/build/generate.js
generated
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
import fs, { readFileSync } from "node:fs";
|
||||
import { basename } from "node:path/posix";
|
||||
import colors from "piccolore";
|
||||
import { getOutDirWithinCwd } from "../../core/build/common.js";
|
||||
import { getTimeStat } from "../../core/build/util.js";
|
||||
import { AstroError } from "../../core/errors/errors.js";
|
||||
import { AstroErrorData } from "../../core/errors/index.js";
|
||||
import { isRemotePath, removeLeadingForwardSlash } from "../../core/path.js";
|
||||
import { getConfiguredImageService } from "../internal.js";
|
||||
import { isESMImportedImage } from "../utils/imageKind.js";
|
||||
import { loadRemoteImage, revalidateRemoteImage } from "./remote.js";
|
||||
async function prepareAssetsGenerationEnv(options, totalCount) {
|
||||
const { settings, logger } = options;
|
||||
let useCache = true;
|
||||
const assetsCacheDir = new URL("assets/", settings.config.cacheDir);
|
||||
const count = { total: totalCount, current: 1 };
|
||||
try {
|
||||
await fs.promises.mkdir(assetsCacheDir, { recursive: true });
|
||||
} catch (err) {
|
||||
logger.warn(
|
||||
null,
|
||||
`An error was encountered while creating the cache directory. Proceeding without caching. Error: ${err}`
|
||||
);
|
||||
useCache = false;
|
||||
}
|
||||
const isServerOutput = settings.buildOutput === "server";
|
||||
let serverRoot, clientRoot;
|
||||
if (isServerOutput) {
|
||||
serverRoot = new URL(".prerender/", settings.config.build.server);
|
||||
clientRoot = settings.config.build.client;
|
||||
} else {
|
||||
serverRoot = getOutDirWithinCwd(settings.config.outDir);
|
||||
clientRoot = settings.config.outDir;
|
||||
}
|
||||
return {
|
||||
logger,
|
||||
isSSR: isServerOutput,
|
||||
count,
|
||||
useCache,
|
||||
assetsCacheDir,
|
||||
serverRoot,
|
||||
clientRoot,
|
||||
imageConfig: settings.config.image,
|
||||
assetsFolder: settings.config.build.assets
|
||||
};
|
||||
}
|
||||
function getFullImagePath(originalFilePath, env) {
|
||||
return new URL(removeLeadingForwardSlash(originalFilePath), env.serverRoot);
|
||||
}
|
||||
async function generateImagesForPath(originalFilePath, transformsAndPath, env) {
|
||||
let originalImage;
|
||||
for (const [_, transform] of transformsAndPath.transforms) {
|
||||
await generateImage(transform.finalPath, transform.transform);
|
||||
}
|
||||
if (transformsAndPath.originalSrcPath && !globalThis.astroAsset.referencedImages?.has(transformsAndPath.originalSrcPath)) {
|
||||
try {
|
||||
if (transformsAndPath.originalSrcPath) {
|
||||
env.logger.debug(
|
||||
"assets",
|
||||
`Deleting ${originalFilePath} as it's not referenced outside of image processing.`
|
||||
);
|
||||
await fs.promises.unlink(getFullImagePath(originalFilePath, env));
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
async function generateImage(filepath, options) {
|
||||
const timeStart = performance.now();
|
||||
const generationData = await generateImageInternal(filepath, options);
|
||||
const timeEnd = performance.now();
|
||||
const timeChange = getTimeStat(timeStart, timeEnd);
|
||||
const timeIncrease = `(+${timeChange})`;
|
||||
const statsText = generationData.cached !== "miss" ? generationData.cached === "hit" ? `(reused cache entry)` : `(revalidated cache entry)` : `(before: ${generationData.weight.before}kB, after: ${generationData.weight.after}kB)`;
|
||||
const count = `(${env.count.current}/${env.count.total})`;
|
||||
env.logger.info(
|
||||
null,
|
||||
` ${colors.green("\u25B6")} ${filepath} ${colors.dim(statsText)} ${colors.dim(timeIncrease)} ${colors.dim(count)}`
|
||||
);
|
||||
env.count.current++;
|
||||
}
|
||||
async function generateImageInternal(filepath, options) {
|
||||
const isLocalImage = isESMImportedImage(options.src);
|
||||
const finalFileURL = new URL("." + filepath, env.clientRoot);
|
||||
const finalFolderURL = new URL("./", finalFileURL);
|
||||
await fs.promises.mkdir(finalFolderURL, { recursive: true });
|
||||
const cacheFile = basename(filepath);
|
||||
const cachedFileURL = new URL(cacheFile, env.assetsCacheDir);
|
||||
const cacheMetaFile = cacheFile + ".json";
|
||||
const cachedMetaFileURL = new URL(cacheMetaFile, env.assetsCacheDir);
|
||||
try {
|
||||
if (isLocalImage) {
|
||||
await fs.promises.copyFile(cachedFileURL, finalFileURL, fs.constants.COPYFILE_FICLONE);
|
||||
return {
|
||||
cached: "hit"
|
||||
};
|
||||
} else {
|
||||
const JSONData = JSON.parse(readFileSync(cachedMetaFileURL, "utf-8"));
|
||||
if (typeof JSONData.expires !== "number") {
|
||||
await Promise.allSettled([
|
||||
fs.promises.unlink(cachedFileURL),
|
||||
fs.promises.unlink(cachedMetaFileURL)
|
||||
]);
|
||||
throw new Error(
|
||||
`Malformed cache entry for ${filepath}, cache will be regenerated for this file.`
|
||||
);
|
||||
}
|
||||
if (JSONData.data) {
|
||||
const { data, ...meta } = JSONData;
|
||||
await Promise.all([
|
||||
fs.promises.writeFile(cachedFileURL, Buffer.from(data, "base64")),
|
||||
writeCacheMetaFile(cachedMetaFileURL, meta, env)
|
||||
]);
|
||||
}
|
||||
if (JSONData.expires > Date.now()) {
|
||||
await fs.promises.copyFile(cachedFileURL, finalFileURL, fs.constants.COPYFILE_FICLONE);
|
||||
return { cached: "hit" };
|
||||
}
|
||||
if (JSONData.etag || JSONData.lastModified) {
|
||||
try {
|
||||
const revalidatedData = await revalidateRemoteImage(options.src, {
|
||||
etag: JSONData.etag,
|
||||
lastModified: JSONData.lastModified
|
||||
});
|
||||
if (revalidatedData.data !== null) {
|
||||
originalImage = revalidatedData;
|
||||
} else {
|
||||
await Promise.all([
|
||||
writeCacheMetaFile(cachedMetaFileURL, revalidatedData, env),
|
||||
fs.promises.copyFile(cachedFileURL, finalFileURL, fs.constants.COPYFILE_FICLONE)
|
||||
]);
|
||||
return { cached: "revalidated" };
|
||||
}
|
||||
} catch (e) {
|
||||
env.logger.warn(
|
||||
null,
|
||||
`An error was encountered while revalidating a cached remote asset. Proceeding with stale cache. ${e}`
|
||||
);
|
||||
await fs.promises.copyFile(cachedFileURL, finalFileURL, fs.constants.COPYFILE_FICLONE);
|
||||
return { cached: "hit" };
|
||||
}
|
||||
}
|
||||
await Promise.allSettled([
|
||||
fs.promises.unlink(cachedFileURL),
|
||||
fs.promises.unlink(cachedMetaFileURL)
|
||||
]);
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.code !== "ENOENT") {
|
||||
throw new Error(`An error was encountered while reading the cache file. Error: ${e}`);
|
||||
}
|
||||
}
|
||||
const originalImagePath = isLocalImage ? options.src.src : options.src;
|
||||
if (!originalImage) {
|
||||
originalImage = await loadImage(originalFilePath, env);
|
||||
}
|
||||
let resultData = {
|
||||
data: void 0,
|
||||
expires: originalImage.expires,
|
||||
etag: originalImage.etag,
|
||||
lastModified: originalImage.lastModified
|
||||
};
|
||||
const imageService = await getConfiguredImageService();
|
||||
try {
|
||||
resultData.data = (await imageService.transform(
|
||||
originalImage.data,
|
||||
{ ...options, src: originalImagePath },
|
||||
env.imageConfig
|
||||
)).data;
|
||||
} catch (e) {
|
||||
if (AstroError.is(e)) {
|
||||
throw e;
|
||||
}
|
||||
const error = new AstroError(
|
||||
{
|
||||
...AstroErrorData.CouldNotTransformImage,
|
||||
message: AstroErrorData.CouldNotTransformImage.message(originalFilePath)
|
||||
},
|
||||
{ cause: e }
|
||||
);
|
||||
throw error;
|
||||
}
|
||||
try {
|
||||
if (env.useCache) {
|
||||
if (isLocalImage) {
|
||||
await fs.promises.writeFile(cachedFileURL, resultData.data);
|
||||
} else {
|
||||
await Promise.all([
|
||||
fs.promises.writeFile(cachedFileURL, resultData.data),
|
||||
writeCacheMetaFile(cachedMetaFileURL, resultData, env)
|
||||
]);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
env.logger.warn(
|
||||
null,
|
||||
`An error was encountered while creating the cache directory. Proceeding without caching. Error: ${e}`
|
||||
);
|
||||
} finally {
|
||||
await fs.promises.writeFile(finalFileURL, resultData.data);
|
||||
}
|
||||
return {
|
||||
cached: "miss",
|
||||
weight: {
|
||||
// Divide by 1024 to get size in kilobytes
|
||||
before: Math.trunc(originalImage.data.byteLength / 1024),
|
||||
after: Math.trunc(Buffer.from(resultData.data).byteLength / 1024)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
async function writeCacheMetaFile(cachedMetaFileURL, resultData, env) {
|
||||
try {
|
||||
return await fs.promises.writeFile(
|
||||
cachedMetaFileURL,
|
||||
JSON.stringify({
|
||||
expires: resultData.expires,
|
||||
etag: resultData.etag,
|
||||
lastModified: resultData.lastModified
|
||||
}),
|
||||
"utf-8"
|
||||
);
|
||||
} catch (e) {
|
||||
env.logger.warn(
|
||||
null,
|
||||
`An error was encountered while writing the cache file for a remote asset. Proceeding without caching this asset. Error: ${e}`
|
||||
);
|
||||
}
|
||||
}
|
||||
function getStaticImageList() {
|
||||
if (!globalThis?.astroAsset?.staticImages) {
|
||||
return /* @__PURE__ */ new Map();
|
||||
}
|
||||
return globalThis.astroAsset.staticImages;
|
||||
}
|
||||
async function loadImage(path, env) {
|
||||
if (isRemotePath(path)) {
|
||||
return await loadRemoteImage(path);
|
||||
}
|
||||
return {
|
||||
data: await fs.promises.readFile(getFullImagePath(path, env)),
|
||||
expires: 0
|
||||
};
|
||||
}
|
||||
export {
|
||||
generateImagesForPath,
|
||||
getStaticImageList,
|
||||
prepareAssetsGenerationEnv
|
||||
};
|
||||
30
node_modules/astro/dist/assets/build/remote.d.ts
generated
vendored
Normal file
30
node_modules/astro/dist/assets/build/remote.d.ts
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
export type RemoteCacheEntry = {
|
||||
data?: string;
|
||||
expires: number;
|
||||
etag?: string;
|
||||
lastModified?: string;
|
||||
};
|
||||
export declare function loadRemoteImage(src: string, fetchFn?: typeof fetch): Promise<{
|
||||
data: Buffer<ArrayBuffer>;
|
||||
expires: number;
|
||||
etag: string | undefined;
|
||||
lastModified: string | undefined;
|
||||
}>;
|
||||
/**
|
||||
* Revalidate a cached remote asset using its entity-tag or modified date.
|
||||
* Uses the [If-None-Match](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match) and [If-Modified-Since](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since)
|
||||
* headers to check with the remote server if the cached version of a remote asset is still up to date.
|
||||
* The remote server may respond that the cached asset is still up-to-date if the entity-tag or modification time matches (304 Not Modified), or respond with an updated asset (200 OK)
|
||||
* @param src - url to remote asset
|
||||
* @param revalidationData - an object containing the stored Entity-Tag of the cached asset and/or the Last Modified time
|
||||
* @returns An object containing the refreshed expiry time and cache headers. `data` will be a `Buffer` of the new image if the asset was modified (200 OK), or `null` if the cached version is still valid (304 Not Modified).
|
||||
*/
|
||||
export declare function revalidateRemoteImage(src: string, revalidationData: {
|
||||
etag?: string;
|
||||
lastModified?: string;
|
||||
}, fetchFn?: typeof fetch): Promise<{
|
||||
data: Buffer<ArrayBuffer> | null;
|
||||
expires: number;
|
||||
etag: string | undefined;
|
||||
lastModified: string | undefined;
|
||||
}>;
|
||||
75
node_modules/astro/dist/assets/build/remote.js
generated
vendored
Normal file
75
node_modules/astro/dist/assets/build/remote.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
import CachePolicy from "http-cache-semantics";
|
||||
async function loadRemoteImage(src, fetchFn = globalThis.fetch) {
|
||||
const req = new Request(src);
|
||||
const res = await fetchFn(req, { redirect: "manual" });
|
||||
if (res.status >= 300 && res.status < 400) {
|
||||
throw new Error(`Failed to load remote image ${src}. The request was redirected.`);
|
||||
}
|
||||
if (!res.ok) {
|
||||
throw new Error(
|
||||
`Failed to load remote image ${src}. The request did not return a 200 OK response. (received ${res.status}))`
|
||||
);
|
||||
}
|
||||
const policy = new CachePolicy(webToCachePolicyRequest(req), webToCachePolicyResponse(res));
|
||||
const expires = policy.storable() ? policy.timeToLive() : 0;
|
||||
return {
|
||||
data: Buffer.from(await res.arrayBuffer()),
|
||||
expires: Date.now() + expires,
|
||||
etag: res.headers.get("Etag") ?? void 0,
|
||||
lastModified: res.headers.get("Last-Modified") ?? void 0
|
||||
};
|
||||
}
|
||||
async function revalidateRemoteImage(src, revalidationData, fetchFn = globalThis.fetch) {
|
||||
const headers = {
|
||||
...revalidationData.etag && { "If-None-Match": revalidationData.etag },
|
||||
...revalidationData.lastModified && { "If-Modified-Since": revalidationData.lastModified }
|
||||
};
|
||||
const req = new Request(src, { headers, cache: "no-cache" });
|
||||
const res = await fetchFn(req, { redirect: "manual" });
|
||||
if (!res.ok && res.status !== 304) {
|
||||
if (res.status >= 300 && res.status < 400) {
|
||||
throw new Error(
|
||||
`Failed to revalidate cached remote image ${src}. The request was redirected.`
|
||||
);
|
||||
}
|
||||
throw new Error(
|
||||
`Failed to revalidate cached remote image ${src}. The request did not return a 200 OK / 304 NOT MODIFIED response. (received ${res.status} ${res.statusText})`
|
||||
);
|
||||
}
|
||||
const data = Buffer.from(await res.arrayBuffer());
|
||||
if (res.ok && !data.length) {
|
||||
return await loadRemoteImage(src, fetchFn);
|
||||
}
|
||||
const policy = new CachePolicy(
|
||||
webToCachePolicyRequest(req),
|
||||
webToCachePolicyResponse(
|
||||
res.ok ? res : new Response(null, { status: 200, headers: res.headers })
|
||||
)
|
||||
// 304 responses are not cacheable, so just use its headers to get the refreshed TTL
|
||||
);
|
||||
const expires = policy.storable() ? policy.timeToLive() : 0;
|
||||
return {
|
||||
data: res.ok ? data : null,
|
||||
expires: Date.now() + expires,
|
||||
// While servers should respond with the same headers as a 200 response, if they don't we should reuse the stored value
|
||||
etag: res.headers.get("Etag") ?? (res.ok ? void 0 : revalidationData.etag),
|
||||
lastModified: res.headers.get("Last-Modified") ?? (res.ok ? void 0 : revalidationData.lastModified)
|
||||
};
|
||||
}
|
||||
function webToCachePolicyRequest({ url, method, headers }) {
|
||||
return {
|
||||
method,
|
||||
url,
|
||||
headers: Object.fromEntries(headers.entries())
|
||||
};
|
||||
}
|
||||
function webToCachePolicyResponse({ status, headers }) {
|
||||
return {
|
||||
status,
|
||||
headers: Object.fromEntries(headers.entries())
|
||||
};
|
||||
}
|
||||
export {
|
||||
loadRemoteImage,
|
||||
revalidateRemoteImage
|
||||
};
|
||||
16
node_modules/astro/dist/assets/consts.d.ts
generated
vendored
Normal file
16
node_modules/astro/dist/assets/consts.d.ts
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
export declare const VIRTUAL_MODULE_ID = "astro:assets";
|
||||
export declare const RESOLVED_VIRTUAL_MODULE_ID: string;
|
||||
export declare const VIRTUAL_SERVICE_ID = "virtual:image-service";
|
||||
export declare const VIRTUAL_GET_IMAGE_ID = "virtual:astro:get-image";
|
||||
export declare const RESOLVED_VIRTUAL_GET_IMAGE_ID: string;
|
||||
export declare const VIRTUAL_IMAGE_STYLES_ID = "virtual:astro:image-styles.css";
|
||||
export declare const RESOLVED_VIRTUAL_IMAGE_STYLES_ID: string;
|
||||
export declare const VALID_INPUT_FORMATS: readonly ["jpeg", "jpg", "png", "tiff", "webp", "gif", "svg", "avif"];
|
||||
/**
|
||||
* Valid formats that our base services support.
|
||||
* Certain formats can be imported (namely SVGs) but will not be processed.
|
||||
*/
|
||||
export declare const VALID_SUPPORTED_FORMATS: readonly ["jpeg", "jpg", "png", "tiff", "webp", "gif", "svg", "avif"];
|
||||
export declare const DEFAULT_OUTPUT_FORMAT: "webp";
|
||||
export declare const VALID_OUTPUT_FORMATS: readonly ["avif", "png", "webp", "jpeg", "jpg", "svg"];
|
||||
export declare const DEFAULT_HASH_PROPS: string[];
|
||||
53
node_modules/astro/dist/assets/consts.js
generated
vendored
Normal file
53
node_modules/astro/dist/assets/consts.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
const VIRTUAL_MODULE_ID = "astro:assets";
|
||||
const RESOLVED_VIRTUAL_MODULE_ID = "\0" + VIRTUAL_MODULE_ID;
|
||||
const VIRTUAL_SERVICE_ID = "virtual:image-service";
|
||||
const VIRTUAL_GET_IMAGE_ID = "virtual:astro:get-image";
|
||||
const RESOLVED_VIRTUAL_GET_IMAGE_ID = "\0" + VIRTUAL_GET_IMAGE_ID;
|
||||
const VIRTUAL_IMAGE_STYLES_ID = "virtual:astro:image-styles.css";
|
||||
const RESOLVED_VIRTUAL_IMAGE_STYLES_ID = "\0" + VIRTUAL_IMAGE_STYLES_ID;
|
||||
const VALID_INPUT_FORMATS = [
|
||||
"jpeg",
|
||||
"jpg",
|
||||
"png",
|
||||
"tiff",
|
||||
"webp",
|
||||
"gif",
|
||||
"svg",
|
||||
"avif"
|
||||
];
|
||||
const VALID_SUPPORTED_FORMATS = [
|
||||
"jpeg",
|
||||
"jpg",
|
||||
"png",
|
||||
"tiff",
|
||||
"webp",
|
||||
"gif",
|
||||
"svg",
|
||||
"avif"
|
||||
];
|
||||
const DEFAULT_OUTPUT_FORMAT = "webp";
|
||||
const VALID_OUTPUT_FORMATS = ["avif", "png", "webp", "jpeg", "jpg", "svg"];
|
||||
const DEFAULT_HASH_PROPS = [
|
||||
"src",
|
||||
"width",
|
||||
"height",
|
||||
"format",
|
||||
"quality",
|
||||
"fit",
|
||||
"position",
|
||||
"background"
|
||||
];
|
||||
export {
|
||||
DEFAULT_HASH_PROPS,
|
||||
DEFAULT_OUTPUT_FORMAT,
|
||||
RESOLVED_VIRTUAL_GET_IMAGE_ID,
|
||||
RESOLVED_VIRTUAL_IMAGE_STYLES_ID,
|
||||
RESOLVED_VIRTUAL_MODULE_ID,
|
||||
VALID_INPUT_FORMATS,
|
||||
VALID_OUTPUT_FORMATS,
|
||||
VALID_SUPPORTED_FORMATS,
|
||||
VIRTUAL_GET_IMAGE_ID,
|
||||
VIRTUAL_IMAGE_STYLES_ID,
|
||||
VIRTUAL_MODULE_ID,
|
||||
VIRTUAL_SERVICE_ID
|
||||
};
|
||||
2
node_modules/astro/dist/assets/endpoint/config.d.ts
generated
vendored
Normal file
2
node_modules/astro/dist/assets/endpoint/config.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { AstroSettings, RoutesList } from '../../types/astro.js';
|
||||
export declare function injectImageEndpoint(settings: AstroSettings, manifest: RoutesList, mode: 'dev' | 'build', cwd?: string): void;
|
||||
20
node_modules/astro/dist/assets/endpoint/config.js
generated
vendored
Normal file
20
node_modules/astro/dist/assets/endpoint/config.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import { resolveInjectedRoute } from "../../core/routing/create-manifest.js";
|
||||
import { parseRoute } from "../../core/routing/parse-route.js";
|
||||
function injectImageEndpoint(settings, manifest, mode, cwd) {
|
||||
manifest.routes.unshift(getImageEndpointData(settings, mode, cwd));
|
||||
}
|
||||
function getImageEndpointData(settings, mode, cwd) {
|
||||
const endpointEntrypoint = settings.config.image.endpoint.entrypoint === void 0 ? mode === "dev" ? "astro/assets/endpoint/dev" : "astro/assets/endpoint/generic" : settings.config.image.endpoint.entrypoint;
|
||||
const component = resolveInjectedRoute(endpointEntrypoint, settings.config.root, cwd).component;
|
||||
return parseRoute(settings.config.image.endpoint.route, settings, {
|
||||
component,
|
||||
type: "endpoint",
|
||||
origin: "internal",
|
||||
isIndex: false,
|
||||
prerender: false,
|
||||
params: []
|
||||
});
|
||||
}
|
||||
export {
|
||||
injectImageEndpoint
|
||||
};
|
||||
5
node_modules/astro/dist/assets/endpoint/dev.d.ts
generated
vendored
Normal file
5
node_modules/astro/dist/assets/endpoint/dev.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { APIRoute } from '../../types/public/common.js';
|
||||
/**
|
||||
* Endpoint used in dev and SSR to serve optimized images by the base image services
|
||||
*/
|
||||
export declare const GET: APIRoute;
|
||||
63
node_modules/astro/dist/assets/endpoint/dev.js
generated
vendored
Normal file
63
node_modules/astro/dist/assets/endpoint/dev.js
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
import { fsDenyGlob, safeModulePaths, viteFSConfig } from "astro:assets";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import { isFileLoadingAllowed } from "vite";
|
||||
import { handleImageRequest, loadRemoteImage } from "./shared.js";
|
||||
function replaceFileSystemReferences(src) {
|
||||
return os.platform().includes("win32") ? src.replace(/^\/@fs\//, "") : src.replace(/^\/@fs/, "");
|
||||
}
|
||||
async function loadLocalImage(src, url) {
|
||||
let returnValue;
|
||||
let fsPath;
|
||||
if (src.startsWith("/@fs/")) {
|
||||
fsPath = replaceFileSystemReferences(src);
|
||||
}
|
||||
if (fsPath && isFileLoadingAllowed(
|
||||
{
|
||||
fsDenyGlob,
|
||||
server: { fs: viteFSConfig },
|
||||
safeModulePaths
|
||||
},
|
||||
fsPath
|
||||
)) {
|
||||
try {
|
||||
returnValue = await readFile(fsPath);
|
||||
} catch {
|
||||
returnValue = void 0;
|
||||
}
|
||||
if (!returnValue) {
|
||||
try {
|
||||
const res = await fetch(new URL(src, url));
|
||||
if (res.ok) {
|
||||
returnValue = Buffer.from(await res.arrayBuffer());
|
||||
}
|
||||
} catch {
|
||||
returnValue = void 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const sourceUrl = new URL(src, url.origin);
|
||||
if (sourceUrl.origin !== url.origin) {
|
||||
returnValue = void 0;
|
||||
}
|
||||
return loadRemoteImage(sourceUrl);
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
const GET = async ({ request }) => {
|
||||
if (!import.meta.env.DEV) {
|
||||
console.error("The dev image endpoint can only be used in dev mode.");
|
||||
return new Response("Invalid endpoint", { status: 500 });
|
||||
}
|
||||
try {
|
||||
return await handleImageRequest({ request, loadLocalImage });
|
||||
} catch (err) {
|
||||
console.error("Could not process image request:", err);
|
||||
return new Response(`Could not process image request: ${err}`, {
|
||||
status: 500
|
||||
});
|
||||
}
|
||||
};
|
||||
export {
|
||||
GET
|
||||
};
|
||||
5
node_modules/astro/dist/assets/endpoint/generic.d.ts
generated
vendored
Normal file
5
node_modules/astro/dist/assets/endpoint/generic.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { APIRoute } from '../../types/public/common.js';
|
||||
/**
|
||||
* Endpoint used in dev and SSR to serve optimized images by the base image services
|
||||
*/
|
||||
export declare const GET: APIRoute;
|
||||
70
node_modules/astro/dist/assets/endpoint/generic.js
generated
vendored
Normal file
70
node_modules/astro/dist/assets/endpoint/generic.js
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
import { imageConfig } from "astro:assets";
|
||||
import { isRemotePath } from "@astrojs/internal-helpers/path";
|
||||
import { isRemoteAllowed } from "@astrojs/internal-helpers/remote";
|
||||
import * as mime from "mrmime";
|
||||
import { getConfiguredImageService } from "../internal.js";
|
||||
import { etag } from "../utils/etag.js";
|
||||
async function loadRemoteImage(src, headers) {
|
||||
try {
|
||||
const res = await fetch(src, {
|
||||
// Forward all headers from the original request
|
||||
headers,
|
||||
redirect: "manual"
|
||||
});
|
||||
if (res.status >= 300 && res.status < 400) {
|
||||
return void 0;
|
||||
}
|
||||
if (!res.ok) {
|
||||
return void 0;
|
||||
}
|
||||
return await res.arrayBuffer();
|
||||
} catch {
|
||||
return void 0;
|
||||
}
|
||||
}
|
||||
const GET = async ({ request }) => {
|
||||
try {
|
||||
const imageService = await getConfiguredImageService();
|
||||
if (!("transform" in imageService)) {
|
||||
throw new Error("Configured image service is not a local service");
|
||||
}
|
||||
const url = new URL(request.url);
|
||||
const transform = await imageService.parseURL(url, imageConfig);
|
||||
if (!transform?.src) {
|
||||
throw new Error("Incorrect transform returned by `parseURL`");
|
||||
}
|
||||
let inputBuffer = void 0;
|
||||
const isRemoteImage = isRemotePath(transform.src);
|
||||
if (isRemoteImage && isRemoteAllowed(transform.src, imageConfig) === false) {
|
||||
return new Response("Forbidden", { status: 403 });
|
||||
}
|
||||
const sourceUrl = new URL(transform.src, url.origin);
|
||||
if (!isRemoteImage && sourceUrl.origin !== url.origin) {
|
||||
return new Response("Forbidden", { status: 403 });
|
||||
}
|
||||
inputBuffer = await loadRemoteImage(sourceUrl, isRemoteImage ? new Headers() : request.headers);
|
||||
if (!inputBuffer) {
|
||||
return new Response("Not Found", { status: 404 });
|
||||
}
|
||||
const { data, format } = await imageService.transform(
|
||||
new Uint8Array(inputBuffer),
|
||||
transform,
|
||||
imageConfig
|
||||
);
|
||||
return new Response(data, {
|
||||
status: 200,
|
||||
headers: {
|
||||
"Content-Type": mime.lookup(format) ?? `image/${format}`,
|
||||
"Cache-Control": "public, max-age=31536000",
|
||||
ETag: etag(data.toString()),
|
||||
Date: (/* @__PURE__ */ new Date()).toUTCString()
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("Could not process image request:", err);
|
||||
return new Response(`Server Error: ${err}`, { status: 500 });
|
||||
}
|
||||
};
|
||||
export {
|
||||
GET
|
||||
};
|
||||
5
node_modules/astro/dist/assets/endpoint/node.d.ts
generated
vendored
Normal file
5
node_modules/astro/dist/assets/endpoint/node.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { APIRoute } from '../../types/public/common.js';
|
||||
/**
|
||||
* Endpoint used in dev and SSR to serve optimized images by the base image services
|
||||
*/
|
||||
export declare const GET: APIRoute;
|
||||
56
node_modules/astro/dist/assets/endpoint/node.js
generated
vendored
Normal file
56
node_modules/astro/dist/assets/endpoint/node.js
generated
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
import { outDir, serverDir } from "astro:assets";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { isParentDirectory } from "@astrojs/internal-helpers/path";
|
||||
import { handleImageRequest } from "./shared.js";
|
||||
async function loadLocalImage(src, url) {
|
||||
const outDirURL = resolveOutDir();
|
||||
const idx = url.pathname.indexOf("/_image");
|
||||
if (idx > 0) {
|
||||
src = src.slice(idx);
|
||||
}
|
||||
if (!URL.canParse("." + src, outDirURL)) {
|
||||
return void 0;
|
||||
}
|
||||
const fileUrl = new URL("." + src, outDirURL);
|
||||
if (fileUrl.protocol !== "file:") {
|
||||
return void 0;
|
||||
}
|
||||
if (!isParentDirectory(fileURLToPath(outDirURL), fileURLToPath(fileUrl))) {
|
||||
return void 0;
|
||||
}
|
||||
try {
|
||||
return await readFile(fileUrl);
|
||||
} catch {
|
||||
return void 0;
|
||||
}
|
||||
}
|
||||
const GET = async ({ request }) => {
|
||||
try {
|
||||
return await handleImageRequest({ request, loadLocalImage });
|
||||
} catch (err) {
|
||||
console.error("Could not process image request:", err);
|
||||
return new Response("Internal Server Error", {
|
||||
status: 500
|
||||
});
|
||||
}
|
||||
};
|
||||
function resolveOutDir() {
|
||||
const serverDirPath = fileURLToPath(serverDir);
|
||||
const rel = path.relative(serverDirPath, fileURLToPath(outDir));
|
||||
const serverFolder = path.basename(serverDirPath);
|
||||
let serverEntryFolderURL = path.dirname(import.meta.url);
|
||||
while (!serverEntryFolderURL.endsWith(serverFolder)) {
|
||||
serverEntryFolderURL = path.dirname(serverEntryFolderURL);
|
||||
}
|
||||
const serverEntryURL = serverEntryFolderURL + "/entry.mjs";
|
||||
const outDirURL = new URL(appendForwardSlash(rel), serverEntryURL);
|
||||
return outDirURL;
|
||||
}
|
||||
function appendForwardSlash(pth) {
|
||||
return pth.endsWith("/") ? pth : pth + "/";
|
||||
}
|
||||
export {
|
||||
GET
|
||||
};
|
||||
5
node_modules/astro/dist/assets/endpoint/shared.d.ts
generated
vendored
Normal file
5
node_modules/astro/dist/assets/endpoint/shared.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
export declare function loadRemoteImage(src: URL): Promise<Buffer | undefined>;
|
||||
export declare const handleImageRequest: ({ request, loadLocalImage, }: {
|
||||
request: Request;
|
||||
loadLocalImage: (src: string, baseUrl: URL) => Promise<Buffer | undefined>;
|
||||
}) => Promise<Response>;
|
||||
67
node_modules/astro/dist/assets/endpoint/shared.js
generated
vendored
Normal file
67
node_modules/astro/dist/assets/endpoint/shared.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
import { imageConfig } from "astro:assets";
|
||||
import { isRemotePath, removeQueryString } from "@astrojs/internal-helpers/path";
|
||||
import { isRemoteAllowed } from "@astrojs/internal-helpers/remote";
|
||||
import * as mime from "mrmime";
|
||||
import { getConfiguredImageService } from "../internal.js";
|
||||
import { etag } from "../utils/etag.js";
|
||||
import { inferSourceFormat } from "../utils/inferSourceFormat.js";
|
||||
async function loadRemoteImage(src) {
|
||||
try {
|
||||
const res = await fetch(src, { redirect: "manual" });
|
||||
if (res.status >= 300 && res.status < 400) {
|
||||
return void 0;
|
||||
}
|
||||
if (!res.ok) {
|
||||
return void 0;
|
||||
}
|
||||
return Buffer.from(await res.arrayBuffer());
|
||||
} catch {
|
||||
return void 0;
|
||||
}
|
||||
}
|
||||
const handleImageRequest = async ({
|
||||
request,
|
||||
loadLocalImage
|
||||
}) => {
|
||||
const imageService = await getConfiguredImageService();
|
||||
if (!("transform" in imageService)) {
|
||||
throw new Error("Configured image service is not a local service");
|
||||
}
|
||||
const url = new URL(request.url);
|
||||
const transform = await imageService.parseURL(url, imageConfig);
|
||||
if (!transform?.src) {
|
||||
return new Response("Invalid request", { status: 400 });
|
||||
}
|
||||
if (transform.format === "svg") {
|
||||
const sourceFormat = inferSourceFormat(transform.src);
|
||||
if (sourceFormat !== "svg") {
|
||||
return new Response("Cannot convert non-SVG source to SVG format", { status: 403 });
|
||||
}
|
||||
}
|
||||
let inputBuffer = void 0;
|
||||
if (isRemotePath(transform.src)) {
|
||||
if (!isRemoteAllowed(transform.src, imageConfig)) {
|
||||
return new Response("Forbidden", { status: 403 });
|
||||
}
|
||||
inputBuffer = await loadRemoteImage(new URL(transform.src));
|
||||
} else {
|
||||
inputBuffer = await loadLocalImage(removeQueryString(transform.src), url);
|
||||
}
|
||||
if (!inputBuffer) {
|
||||
return new Response("Internal Server Error", { status: 500 });
|
||||
}
|
||||
const { data, format } = await imageService.transform(inputBuffer, transform, imageConfig);
|
||||
return new Response(data, {
|
||||
status: 200,
|
||||
headers: {
|
||||
"Content-Type": mime.lookup(format) ?? `image/${format}`,
|
||||
"Cache-Control": "public, max-age=31536000",
|
||||
ETag: etag(data.toString()),
|
||||
Date: (/* @__PURE__ */ new Date()).toUTCString()
|
||||
}
|
||||
});
|
||||
};
|
||||
export {
|
||||
handleImageRequest,
|
||||
loadRemoteImage
|
||||
};
|
||||
59
node_modules/astro/dist/assets/fonts/config.d.ts
generated
vendored
Normal file
59
node_modules/astro/dist/assets/fonts/config.d.ts
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
import * as z from 'zod/v4';
|
||||
import type { FontProvider } from './types.js';
|
||||
export declare const WeightSchema: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
||||
export declare const StyleSchema: z.ZodEnum<{
|
||||
normal: "normal";
|
||||
italic: "italic";
|
||||
oblique: "oblique";
|
||||
}>;
|
||||
export declare const DisplaySchema: z.ZodEnum<{
|
||||
optional: "optional";
|
||||
auto: "auto";
|
||||
block: "block";
|
||||
swap: "swap";
|
||||
fallback: "fallback";
|
||||
}>;
|
||||
export declare const FontProviderSchema: z.ZodCustom<FontProvider<never>, FontProvider<never>>;
|
||||
export declare const FontFamilySchema: z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
cssVariable: z.ZodString;
|
||||
provider: z.ZodCustom<FontProvider<never>, FontProvider<never>>;
|
||||
weights: z.ZodOptional<z.ZodTuple<[z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>], z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
|
||||
styles: z.ZodOptional<z.ZodTuple<[z.ZodEnum<{
|
||||
normal: "normal";
|
||||
italic: "italic";
|
||||
oblique: "oblique";
|
||||
}>], z.ZodEnum<{
|
||||
normal: "normal";
|
||||
italic: "italic";
|
||||
oblique: "oblique";
|
||||
}>>>;
|
||||
subsets: z.ZodOptional<z.ZodTuple<[z.ZodString], z.ZodString>>;
|
||||
formats: z.ZodOptional<z.ZodTuple<[z.ZodEnum<{
|
||||
woff2: "woff2";
|
||||
woff: "woff";
|
||||
otf: "otf";
|
||||
ttf: "ttf";
|
||||
eot: "eot";
|
||||
}>], z.ZodEnum<{
|
||||
woff2: "woff2";
|
||||
woff: "woff";
|
||||
otf: "otf";
|
||||
ttf: "ttf";
|
||||
eot: "eot";
|
||||
}>>>;
|
||||
fallbacks: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
||||
optimizedFallbacks: z.ZodOptional<z.ZodBoolean>;
|
||||
display: z.ZodOptional<z.ZodEnum<{
|
||||
optional: "optional";
|
||||
auto: "auto";
|
||||
block: "block";
|
||||
swap: "swap";
|
||||
fallback: "fallback";
|
||||
}>>;
|
||||
stretch: z.ZodOptional<z.ZodString>;
|
||||
featureSettings: z.ZodOptional<z.ZodString>;
|
||||
variationSettings: z.ZodOptional<z.ZodString>;
|
||||
unicodeRange: z.ZodOptional<z.ZodTuple<[z.ZodString], z.ZodString>>;
|
||||
options: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
|
||||
}, z.core.$strict>;
|
||||
40
node_modules/astro/dist/assets/fonts/config.js
generated
vendored
Normal file
40
node_modules/astro/dist/assets/fonts/config.js
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import * as z from "zod/v4";
|
||||
import { FONT_TYPES } from "./constants.js";
|
||||
const WeightSchema = z.union([z.string(), z.number()]);
|
||||
const StyleSchema = z.enum(["normal", "italic", "oblique"]);
|
||||
const DisplaySchema = z.enum(["auto", "block", "swap", "fallback", "optional"]);
|
||||
const FormatSchema = z.enum(FONT_TYPES);
|
||||
const _FontProviderSchema = z.strictObject({
|
||||
name: z.string(),
|
||||
config: z.record(z.string(), z.any()).optional(),
|
||||
init: z.custom((v) => typeof v === "function").optional(),
|
||||
resolveFont: z.custom((v) => typeof v === "function"),
|
||||
listFonts: z.custom((v) => typeof v === "function").optional()
|
||||
});
|
||||
const FontProviderSchema = z.custom((v) => {
|
||||
return _FontProviderSchema.safeParse(v).success;
|
||||
}, "Invalid FontProvider object");
|
||||
const FontFamilySchema = z.object({
|
||||
name: z.string(),
|
||||
cssVariable: z.string(),
|
||||
provider: FontProviderSchema,
|
||||
weights: z.tuple([WeightSchema], WeightSchema).optional(),
|
||||
styles: z.tuple([StyleSchema], StyleSchema).optional(),
|
||||
subsets: z.tuple([z.string()], z.string()).optional(),
|
||||
formats: z.tuple([FormatSchema], FormatSchema).optional(),
|
||||
fallbacks: z.array(z.string()).optional(),
|
||||
optimizedFallbacks: z.boolean().optional(),
|
||||
display: DisplaySchema.optional(),
|
||||
stretch: z.string().optional(),
|
||||
featureSettings: z.string().optional(),
|
||||
variationSettings: z.string().optional(),
|
||||
unicodeRange: z.tuple([z.string()], z.string()).optional(),
|
||||
options: z.record(z.string(), z.any()).optional()
|
||||
}).strict();
|
||||
export {
|
||||
DisplaySchema,
|
||||
FontFamilySchema,
|
||||
FontProviderSchema,
|
||||
StyleSchema,
|
||||
WeightSchema
|
||||
};
|
||||
15
node_modules/astro/dist/assets/fonts/constants.d.ts
generated
vendored
Normal file
15
node_modules/astro/dist/assets/fonts/constants.d.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import type { Defaults, FontType } from './types.js';
|
||||
export declare const DEFAULTS: Defaults;
|
||||
export declare const VIRTUAL_MODULE_ID = "virtual:astro:assets/fonts/internal";
|
||||
export declare const RESOLVED_VIRTUAL_MODULE_ID: string;
|
||||
export declare const RUNTIME_VIRTUAL_MODULE_ID = "virtual:astro:assets/fonts/runtime";
|
||||
export declare const RESOLVED_RUNTIME_VIRTUAL_MODULE_ID: string;
|
||||
export declare const ASSETS_DIR = "fonts";
|
||||
export declare const CACHE_DIR = "./fonts/";
|
||||
export declare const FONT_TYPES: readonly ["woff2", "woff", "otf", "ttf", "eot"];
|
||||
export declare const FONT_FORMATS: Array<{
|
||||
type: FontType;
|
||||
format: string;
|
||||
}>;
|
||||
export declare const GENERIC_FALLBACK_NAMES: readonly ["serif", "sans-serif", "monospace", "cursive", "fantasy", "system-ui", "ui-serif", "ui-sans-serif", "ui-monospace", "ui-rounded", "emoji", "math", "fangsong"];
|
||||
export declare const FONTS_TYPES_FILE = "fonts.d.ts";
|
||||
52
node_modules/astro/dist/assets/fonts/constants.js
generated
vendored
Normal file
52
node_modules/astro/dist/assets/fonts/constants.js
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
const DEFAULTS = {
|
||||
weights: ["400"],
|
||||
styles: ["normal", "italic"],
|
||||
subsets: ["latin"],
|
||||
// Technically serif is the browser default but most websites these days use sans-serif
|
||||
fallbacks: ["sans-serif"],
|
||||
optimizedFallbacks: true,
|
||||
formats: ["woff2"]
|
||||
};
|
||||
const VIRTUAL_MODULE_ID = "virtual:astro:assets/fonts/internal";
|
||||
const RESOLVED_VIRTUAL_MODULE_ID = "\0" + VIRTUAL_MODULE_ID;
|
||||
const RUNTIME_VIRTUAL_MODULE_ID = "virtual:astro:assets/fonts/runtime";
|
||||
const RESOLVED_RUNTIME_VIRTUAL_MODULE_ID = "\0" + RUNTIME_VIRTUAL_MODULE_ID;
|
||||
const ASSETS_DIR = "fonts";
|
||||
const CACHE_DIR = "./fonts/";
|
||||
const FONT_TYPES = ["woff2", "woff", "otf", "ttf", "eot"];
|
||||
const FONT_FORMATS = [
|
||||
{ type: "woff2", format: "woff2" },
|
||||
{ type: "woff", format: "woff" },
|
||||
{ type: "otf", format: "opentype" },
|
||||
{ type: "ttf", format: "truetype" },
|
||||
{ type: "eot", format: "embedded-opentype" }
|
||||
];
|
||||
const GENERIC_FALLBACK_NAMES = [
|
||||
"serif",
|
||||
"sans-serif",
|
||||
"monospace",
|
||||
"cursive",
|
||||
"fantasy",
|
||||
"system-ui",
|
||||
"ui-serif",
|
||||
"ui-sans-serif",
|
||||
"ui-monospace",
|
||||
"ui-rounded",
|
||||
"emoji",
|
||||
"math",
|
||||
"fangsong"
|
||||
];
|
||||
const FONTS_TYPES_FILE = "fonts.d.ts";
|
||||
export {
|
||||
ASSETS_DIR,
|
||||
CACHE_DIR,
|
||||
DEFAULTS,
|
||||
FONTS_TYPES_FILE,
|
||||
FONT_FORMATS,
|
||||
FONT_TYPES,
|
||||
GENERIC_FALLBACK_NAMES,
|
||||
RESOLVED_RUNTIME_VIRTUAL_MODULE_ID,
|
||||
RESOLVED_VIRTUAL_MODULE_ID,
|
||||
RUNTIME_VIRTUAL_MODULE_ID,
|
||||
VIRTUAL_MODULE_ID
|
||||
};
|
||||
9
node_modules/astro/dist/assets/fonts/core/collect-component-data.d.ts
generated
vendored
Normal file
9
node_modules/astro/dist/assets/fonts/core/collect-component-data.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import type { CssRenderer } from '../definitions.js';
|
||||
import type { Collaborator, ComponentDataByCssVariable, Defaults, FontFamilyAssets } from '../types.js';
|
||||
import type { optimizeFallbacks as _optimizeFallbacks } from './optimize-fallbacks.js';
|
||||
export declare function collectComponentData({ fontFamilyAssets, cssRenderer, defaults, optimizeFallbacks, }: {
|
||||
fontFamilyAssets: Array<FontFamilyAssets>;
|
||||
cssRenderer: CssRenderer;
|
||||
defaults: Pick<Defaults, 'fallbacks' | 'optimizedFallbacks'>;
|
||||
optimizeFallbacks: Collaborator<typeof _optimizeFallbacks, 'family' | 'fallbacks' | 'collectedFonts'>;
|
||||
}): Promise<ComponentDataByCssVariable>;
|
||||
47
node_modules/astro/dist/assets/fonts/core/collect-component-data.js
generated
vendored
Normal file
47
node_modules/astro/dist/assets/fonts/core/collect-component-data.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
import { unifontFontFaceDataToProperties } from "../utils.js";
|
||||
async function collectComponentData({
|
||||
fontFamilyAssets,
|
||||
cssRenderer,
|
||||
defaults,
|
||||
optimizeFallbacks
|
||||
}) {
|
||||
const componentDataByCssVariable = /* @__PURE__ */ new Map();
|
||||
for (const { family, fonts, collectedFontsForMetricsByUniqueKey, preloads } of fontFamilyAssets) {
|
||||
let css = "";
|
||||
for (const data of fonts) {
|
||||
css += cssRenderer.generateFontFace(
|
||||
family.uniqueName,
|
||||
unifontFontFaceDataToProperties({
|
||||
src: data.src,
|
||||
weight: data.weight,
|
||||
style: data.style,
|
||||
// User settings override the generated font settings
|
||||
display: data.display ?? family.display,
|
||||
unicodeRange: data.unicodeRange ?? family.unicodeRange,
|
||||
stretch: data.stretch ?? family.stretch,
|
||||
featureSettings: data.featureSettings ?? family.featureSettings,
|
||||
variationSettings: data.variationSettings ?? family.variationSettings
|
||||
})
|
||||
);
|
||||
}
|
||||
const fallbacks = family.fallbacks ?? defaults.fallbacks;
|
||||
const cssVarValues = [family.uniqueName];
|
||||
const optimizeFallbacksResult = family.optimizedFallbacks ?? defaults.optimizedFallbacks ? await optimizeFallbacks({
|
||||
family,
|
||||
fallbacks,
|
||||
collectedFonts: Array.from(collectedFontsForMetricsByUniqueKey.values())
|
||||
}) : null;
|
||||
if (optimizeFallbacksResult) {
|
||||
css += optimizeFallbacksResult.css;
|
||||
cssVarValues.push(...optimizeFallbacksResult.fallbacks);
|
||||
} else {
|
||||
cssVarValues.push(...fallbacks);
|
||||
}
|
||||
css += cssRenderer.generateCssVariable(family.cssVariable, cssVarValues);
|
||||
componentDataByCssVariable.set(family.cssVariable, { preloads, css });
|
||||
}
|
||||
return componentDataByCssVariable;
|
||||
}
|
||||
export {
|
||||
collectComponentData
|
||||
};
|
||||
17
node_modules/astro/dist/assets/fonts/core/collect-font-assets-from-faces.d.ts
generated
vendored
Normal file
17
node_modules/astro/dist/assets/fonts/core/collect-font-assets-from-faces.d.ts
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import type * as unifont from 'unifont';
|
||||
import type { FontFileIdGenerator, Hasher } from '../definitions.js';
|
||||
import type { Defaults, FontFileById, PreloadData, ResolvedFontFamily } from '../types.js';
|
||||
import type { CollectedFontForMetrics } from './optimize-fallbacks.js';
|
||||
export declare function collectFontAssetsFromFaces({ fonts, fontFileIdGenerator, family, fontFilesIds, collectedFontsIds, hasher, defaults, }: {
|
||||
fonts: Array<unifont.FontFaceData>;
|
||||
fontFileIdGenerator: FontFileIdGenerator;
|
||||
family: Pick<ResolvedFontFamily, 'cssVariable' | 'fallbacks'>;
|
||||
fontFilesIds: Set<string>;
|
||||
collectedFontsIds: Set<string>;
|
||||
hasher: Hasher;
|
||||
defaults: Pick<Defaults, 'fallbacks'>;
|
||||
}): {
|
||||
fontFileById: FontFileById;
|
||||
preloads: PreloadData[];
|
||||
collectedFontsForMetricsByUniqueKey: Map<string, CollectedFontForMetrics>;
|
||||
};
|
||||
71
node_modules/astro/dist/assets/fonts/core/collect-font-assets-from-faces.js
generated
vendored
Normal file
71
node_modules/astro/dist/assets/fonts/core/collect-font-assets-from-faces.js
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
import { FONT_FORMATS } from "../constants.js";
|
||||
import { renderFontWeight } from "../utils.js";
|
||||
function collectFontAssetsFromFaces({
|
||||
fonts,
|
||||
fontFileIdGenerator,
|
||||
family,
|
||||
fontFilesIds,
|
||||
collectedFontsIds,
|
||||
hasher,
|
||||
defaults
|
||||
}) {
|
||||
const fontFileById = /* @__PURE__ */ new Map();
|
||||
const collectedFontsForMetricsByUniqueKey = /* @__PURE__ */ new Map();
|
||||
const preloads = [];
|
||||
for (const font of fonts) {
|
||||
let index = 0;
|
||||
for (const source of font.src) {
|
||||
if ("name" in source) {
|
||||
continue;
|
||||
}
|
||||
const format = FONT_FORMATS.find((e) => e.format === source.format);
|
||||
const originalUrl = source.originalURL;
|
||||
const id = fontFileIdGenerator.generate({
|
||||
cssVariable: family.cssVariable,
|
||||
font,
|
||||
originalUrl,
|
||||
type: format.type
|
||||
});
|
||||
if (!fontFilesIds.has(id) && !fontFileById.has(id)) {
|
||||
fontFileById.set(id, { url: originalUrl, init: font.meta?.init });
|
||||
if (index === 0) {
|
||||
preloads.push({
|
||||
style: font.style,
|
||||
subset: font.meta?.subset,
|
||||
type: format.type,
|
||||
url: source.url,
|
||||
weight: renderFontWeight(font.weight)
|
||||
});
|
||||
}
|
||||
}
|
||||
const collected = {
|
||||
id,
|
||||
url: originalUrl,
|
||||
init: font.meta?.init,
|
||||
data: {
|
||||
weight: font.weight,
|
||||
style: font.style,
|
||||
meta: {
|
||||
subset: font.meta?.subset
|
||||
}
|
||||
}
|
||||
};
|
||||
const collectedKey = hasher.hashObject(collected.data);
|
||||
const fallbacks = family.fallbacks ?? defaults.fallbacks;
|
||||
if (fallbacks.length > 0 && // If the same data has already been sent for this family, we don't want to have
|
||||
// duplicated fallbacks. Such scenario can occur with unicode ranges.
|
||||
!collectedFontsIds.has(collectedKey) && !collectedFontsForMetricsByUniqueKey.has(collectedKey)) {
|
||||
collectedFontsForMetricsByUniqueKey.set(collectedKey, collected);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
return {
|
||||
fontFileById,
|
||||
preloads,
|
||||
collectedFontsForMetricsByUniqueKey
|
||||
};
|
||||
}
|
||||
export {
|
||||
collectFontAssetsFromFaces
|
||||
};
|
||||
4
node_modules/astro/dist/assets/fonts/core/collect-font-data.d.ts
generated
vendored
Normal file
4
node_modules/astro/dist/assets/fonts/core/collect-font-data.d.ts
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import type { FontDataByCssVariable, FontFamilyAssets } from '../types.js';
|
||||
export declare function collectFontData(fontFamilyAssets: Array<Pick<FontFamilyAssets, 'fonts'> & {
|
||||
family: Pick<FontFamilyAssets['family'], 'cssVariable'>;
|
||||
}>): FontDataByCssVariable;
|
||||
23
node_modules/astro/dist/assets/fonts/core/collect-font-data.js
generated
vendored
Normal file
23
node_modules/astro/dist/assets/fonts/core/collect-font-data.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import { renderFontWeight } from "../utils.js";
|
||||
function collectFontData(fontFamilyAssets) {
|
||||
const fontDataByCssVariable = {};
|
||||
for (const { family, fonts } of fontFamilyAssets) {
|
||||
const fontData = [];
|
||||
for (const data of fonts) {
|
||||
fontData.push({
|
||||
weight: renderFontWeight(data.weight),
|
||||
style: data.style,
|
||||
src: data.src.filter((src) => "url" in src).map((src) => ({
|
||||
url: src.url,
|
||||
format: src.format,
|
||||
tech: src.tech
|
||||
}))
|
||||
});
|
||||
}
|
||||
fontDataByCssVariable[family.cssVariable] = fontData;
|
||||
}
|
||||
return fontDataByCssVariable;
|
||||
}
|
||||
export {
|
||||
collectFontData
|
||||
};
|
||||
20
node_modules/astro/dist/assets/fonts/core/compute-font-families-assets.d.ts
generated
vendored
Normal file
20
node_modules/astro/dist/assets/fonts/core/compute-font-families-assets.d.ts
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import type { AstroLogger } from '../../../core/logger/core.js';
|
||||
import type { FontResolver, StringMatcher } from '../definitions.js';
|
||||
import type { Collaborator, Defaults, FontFileById, ResolvedFontFamily } from '../types.js';
|
||||
import type { collectFontAssetsFromFaces as _collectFontAssetsFromFaces } from './collect-font-assets-from-faces.js';
|
||||
import type { filterAndTransformFontFaces as _filterAndTransformFontFaces } from './filter-and-transform-font-faces.js';
|
||||
import type { getOrCreateFontFamilyAssets as _getOrCreateFontFamilyAssets } from './get-or-create-font-family-assets.js';
|
||||
export declare function computeFontFamiliesAssets({ resolvedFamilies, fontResolver, logger, bold, defaults, stringMatcher, getOrCreateFontFamilyAssets, collectFontAssetsFromFaces, filterAndTransformFontFaces, }: {
|
||||
resolvedFamilies: Array<ResolvedFontFamily>;
|
||||
fontResolver: FontResolver;
|
||||
logger: AstroLogger;
|
||||
bold: (input: string) => string;
|
||||
defaults: Defaults;
|
||||
stringMatcher: StringMatcher;
|
||||
getOrCreateFontFamilyAssets: Collaborator<typeof _getOrCreateFontFamilyAssets, 'family' | 'fontFamilyAssetsByUniqueKey'>;
|
||||
filterAndTransformFontFaces: Collaborator<typeof _filterAndTransformFontFaces, 'family' | 'fonts'>;
|
||||
collectFontAssetsFromFaces: Collaborator<typeof _collectFontAssetsFromFaces, 'family' | 'fonts' | 'collectedFontsIds' | 'fontFilesIds'>;
|
||||
}): Promise<{
|
||||
fontFamilyAssets: import("../types.js").FontFamilyAssets[];
|
||||
fontFileById: FontFileById;
|
||||
}>;
|
||||
67
node_modules/astro/dist/assets/fonts/core/compute-font-families-assets.js
generated
vendored
Normal file
67
node_modules/astro/dist/assets/fonts/core/compute-font-families-assets.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
async function computeFontFamiliesAssets({
|
||||
resolvedFamilies,
|
||||
fontResolver,
|
||||
logger,
|
||||
bold,
|
||||
defaults,
|
||||
stringMatcher,
|
||||
getOrCreateFontFamilyAssets,
|
||||
collectFontAssetsFromFaces,
|
||||
filterAndTransformFontFaces
|
||||
}) {
|
||||
const fontFamilyAssetsByUniqueKey = /* @__PURE__ */ new Map();
|
||||
const fontFileById = /* @__PURE__ */ new Map();
|
||||
for (const family of resolvedFamilies) {
|
||||
const fontAssets = getOrCreateFontFamilyAssets({
|
||||
fontFamilyAssetsByUniqueKey,
|
||||
family
|
||||
});
|
||||
const _fonts = await fontResolver.resolveFont({
|
||||
familyName: family.name,
|
||||
provider: family.provider,
|
||||
// We do not merge the defaults, we only provide defaults as a fallback
|
||||
weights: family.weights ?? defaults.weights,
|
||||
styles: family.styles ?? defaults.styles,
|
||||
subsets: family.subsets ?? defaults.subsets,
|
||||
formats: family.formats ?? defaults.formats,
|
||||
options: family.options
|
||||
});
|
||||
if (_fonts.length === 0) {
|
||||
logger.warn(
|
||||
"assets",
|
||||
`No data found for font family ${bold(family.name)}. Review your configuration`
|
||||
);
|
||||
const availableFamilies = await fontResolver.listFonts({ provider: family.provider });
|
||||
if (availableFamilies && availableFamilies.length > 0 && !availableFamilies.includes(family.name)) {
|
||||
logger.warn(
|
||||
"assets",
|
||||
`${bold(family.name)} font family cannot be retrieved by the provider. Did you mean ${bold(stringMatcher.getClosestMatch(family.name, availableFamilies))}?`
|
||||
);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
fontAssets.fonts.push(
|
||||
...filterAndTransformFontFaces({
|
||||
fonts: _fonts,
|
||||
family
|
||||
})
|
||||
);
|
||||
const result = collectFontAssetsFromFaces({
|
||||
fonts: fontAssets.fonts,
|
||||
family,
|
||||
fontFilesIds: new Set(fontFileById.keys()),
|
||||
collectedFontsIds: new Set(fontAssets.collectedFontsForMetricsByUniqueKey.keys())
|
||||
});
|
||||
for (const [key, value] of result.fontFileById.entries()) {
|
||||
fontFileById.set(key, value);
|
||||
}
|
||||
for (const [key, value] of result.collectedFontsForMetricsByUniqueKey.entries()) {
|
||||
fontAssets.collectedFontsForMetricsByUniqueKey.set(key, value);
|
||||
}
|
||||
fontAssets.preloads.push(...result.preloads);
|
||||
}
|
||||
return { fontFamilyAssets: Array.from(fontFamilyAssetsByUniqueKey.values()), fontFileById };
|
||||
}
|
||||
export {
|
||||
computeFontFamiliesAssets
|
||||
};
|
||||
20
node_modules/astro/dist/assets/fonts/core/filter-and-transform-font-faces.d.ts
generated
vendored
Normal file
20
node_modules/astro/dist/assets/fonts/core/filter-and-transform-font-faces.d.ts
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import type * as unifont from 'unifont';
|
||||
import type { FontFileIdGenerator, FontTypeExtractor, UrlResolver } from '../definitions.js';
|
||||
import type { ResolvedFontFamily } from '../types.js';
|
||||
export declare function filterAndTransformFontFaces({ fonts, fontTypeExtractor, fontFileIdGenerator, urlResolver, family, }: {
|
||||
fonts: Array<unifont.FontFaceData>;
|
||||
fontTypeExtractor: FontTypeExtractor;
|
||||
fontFileIdGenerator: FontFileIdGenerator;
|
||||
urlResolver: UrlResolver;
|
||||
family: Pick<ResolvedFontFamily, 'cssVariable'>;
|
||||
}): {
|
||||
src: (unifont.LocalFontSource | unifont.RemoteFontSource)[];
|
||||
display?: "auto" | "block" | "swap" | "fallback" | "optional";
|
||||
weight?: string | number | [number, number];
|
||||
stretch?: string;
|
||||
style?: string;
|
||||
unicodeRange?: string[];
|
||||
featureSettings?: string;
|
||||
variationSettings?: string;
|
||||
meta?: unifont.FontFaceMeta;
|
||||
}[];
|
||||
39
node_modules/astro/dist/assets/fonts/core/filter-and-transform-font-faces.js
generated
vendored
Normal file
39
node_modules/astro/dist/assets/fonts/core/filter-and-transform-font-faces.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import { FONT_FORMATS } from "../constants.js";
|
||||
function filterAndTransformFontFaces({
|
||||
fonts,
|
||||
fontTypeExtractor,
|
||||
fontFileIdGenerator,
|
||||
urlResolver,
|
||||
family
|
||||
}) {
|
||||
return fonts.filter((font) => typeof font.meta?.priority === "number" ? font.meta.priority <= 1 : true).map((font) => ({
|
||||
...font,
|
||||
src: font.src.map((source) => {
|
||||
if ("name" in source) {
|
||||
return source;
|
||||
}
|
||||
const originalUrl = source.url.startsWith("//") ? `https:${source.url}` : source.url;
|
||||
let format = FONT_FORMATS.find((e) => e.format === source.format);
|
||||
if (!format) {
|
||||
format = FONT_FORMATS.find((e) => e.type === fontTypeExtractor.extract(source.url));
|
||||
}
|
||||
const id = fontFileIdGenerator.generate({
|
||||
cssVariable: family.cssVariable,
|
||||
font,
|
||||
originalUrl,
|
||||
type: format.type
|
||||
});
|
||||
const url = urlResolver.resolve(id);
|
||||
const newSource = {
|
||||
originalURL: originalUrl,
|
||||
url,
|
||||
format: format.format,
|
||||
tech: source.tech
|
||||
};
|
||||
return newSource;
|
||||
})
|
||||
}));
|
||||
}
|
||||
export {
|
||||
filterAndTransformFontFaces
|
||||
};
|
||||
2
node_modules/astro/dist/assets/fonts/core/filter-preloads.d.ts
generated
vendored
Normal file
2
node_modules/astro/dist/assets/fonts/core/filter-preloads.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { PreloadData, PreloadFilter } from '../types.js';
|
||||
export declare function filterPreloads(data: Array<PreloadData>, preload: PreloadFilter): Array<PreloadData> | null;
|
||||
37
node_modules/astro/dist/assets/fonts/core/filter-preloads.js
generated
vendored
Normal file
37
node_modules/astro/dist/assets/fonts/core/filter-preloads.js
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
function filterPreloads(data, preload) {
|
||||
if (!preload) {
|
||||
return null;
|
||||
}
|
||||
if (preload === true) {
|
||||
return data;
|
||||
}
|
||||
return data.filter(
|
||||
({ weight, style, subset }) => preload.some((p) => {
|
||||
if (p.weight !== void 0 && weight !== void 0 && !checkWeight(p.weight.toString(), weight)) {
|
||||
return false;
|
||||
}
|
||||
if (p.style !== void 0 && p.style !== style) {
|
||||
return false;
|
||||
}
|
||||
if (p.subset !== void 0 && p.subset !== subset) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
);
|
||||
}
|
||||
function checkWeight(input, target) {
|
||||
const trimmedInput = input.trim();
|
||||
if (trimmedInput.includes(" ")) {
|
||||
return trimmedInput === target;
|
||||
}
|
||||
if (target.includes(" ")) {
|
||||
const [a, b] = target.split(" ");
|
||||
const parsedInput = Number.parseInt(input);
|
||||
return parsedInput >= Number.parseInt(a) && parsedInput <= Number.parseInt(b);
|
||||
}
|
||||
return input === target;
|
||||
}
|
||||
export {
|
||||
filterPreloads
|
||||
};
|
||||
8
node_modules/astro/dist/assets/fonts/core/get-or-create-font-family-assets.d.ts
generated
vendored
Normal file
8
node_modules/astro/dist/assets/fonts/core/get-or-create-font-family-assets.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { AstroLogger } from '../../../core/logger/core.js';
|
||||
import type { FontFamilyAssetsByUniqueKey, ResolvedFontFamily } from '../types.js';
|
||||
export declare function getOrCreateFontFamilyAssets({ fontFamilyAssetsByUniqueKey, logger, bold, family, }: {
|
||||
fontFamilyAssetsByUniqueKey: FontFamilyAssetsByUniqueKey;
|
||||
logger: AstroLogger;
|
||||
bold: (input: string) => string;
|
||||
family: ResolvedFontFamily;
|
||||
}): import("../types.js").FontFamilyAssets;
|
||||
34
node_modules/astro/dist/assets/fonts/core/get-or-create-font-family-assets.js
generated
vendored
Normal file
34
node_modules/astro/dist/assets/fonts/core/get-or-create-font-family-assets.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
function getOrCreateFontFamilyAssets({
|
||||
fontFamilyAssetsByUniqueKey,
|
||||
logger,
|
||||
bold,
|
||||
family
|
||||
}) {
|
||||
const key = `${family.cssVariable}:${family.name}:${family.provider.name}`;
|
||||
let fontAssets = fontFamilyAssetsByUniqueKey.get(key);
|
||||
if (!fontAssets) {
|
||||
if (Array.from(fontFamilyAssetsByUniqueKey.keys()).find(
|
||||
(k) => k.startsWith(`${family.cssVariable}:`)
|
||||
)) {
|
||||
logger.warn(
|
||||
"assets",
|
||||
`Several font families have been registered for the ${bold(family.cssVariable)} cssVariable but they do not share the same name and provider.`
|
||||
);
|
||||
logger.warn(
|
||||
"assets",
|
||||
"These families will not be merged together. The last occurrence will override previous families for this cssVariable. Review your Astro configuration."
|
||||
);
|
||||
}
|
||||
fontAssets = {
|
||||
family,
|
||||
fonts: [],
|
||||
collectedFontsForMetricsByUniqueKey: /* @__PURE__ */ new Map(),
|
||||
preloads: []
|
||||
};
|
||||
fontFamilyAssetsByUniqueKey.set(key, fontAssets);
|
||||
}
|
||||
return fontAssets;
|
||||
}
|
||||
export {
|
||||
getOrCreateFontFamilyAssets
|
||||
};
|
||||
16
node_modules/astro/dist/assets/fonts/core/optimize-fallbacks.d.ts
generated
vendored
Normal file
16
node_modules/astro/dist/assets/fonts/core/optimize-fallbacks.d.ts
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import type * as unifont from 'unifont';
|
||||
import type { FontMetricsResolver, SystemFallbacksProvider } from '../definitions.js';
|
||||
import type { FontFileData, ResolvedFontFamily } from '../types.js';
|
||||
export interface CollectedFontForMetrics extends FontFileData {
|
||||
data: Partial<unifont.FontFaceData>;
|
||||
}
|
||||
export declare function optimizeFallbacks({ family, fallbacks: _fallbacks, collectedFonts, systemFallbacksProvider, fontMetricsResolver, }: {
|
||||
family: Pick<ResolvedFontFamily, 'name' | 'uniqueName'>;
|
||||
fallbacks: Array<string>;
|
||||
collectedFonts: Array<CollectedFontForMetrics>;
|
||||
systemFallbacksProvider: SystemFallbacksProvider;
|
||||
fontMetricsResolver: FontMetricsResolver;
|
||||
}): Promise<null | {
|
||||
css: string;
|
||||
fallbacks: Array<string>;
|
||||
}>;
|
||||
46
node_modules/astro/dist/assets/fonts/core/optimize-fallbacks.js
generated
vendored
Normal file
46
node_modules/astro/dist/assets/fonts/core/optimize-fallbacks.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
import { isGenericFontFamily, unifontFontFaceDataToProperties } from "../utils.js";
|
||||
async function optimizeFallbacks({
|
||||
family,
|
||||
fallbacks: _fallbacks,
|
||||
collectedFonts,
|
||||
systemFallbacksProvider,
|
||||
fontMetricsResolver
|
||||
}) {
|
||||
let fallbacks = [..._fallbacks];
|
||||
if (fallbacks.length === 0 || collectedFonts.length === 0) {
|
||||
return null;
|
||||
}
|
||||
const lastFallback = fallbacks[fallbacks.length - 1];
|
||||
if (!isGenericFontFamily(lastFallback)) {
|
||||
return null;
|
||||
}
|
||||
const localFonts = systemFallbacksProvider.getLocalFonts(lastFallback);
|
||||
if (!localFonts || localFonts.length === 0) {
|
||||
return null;
|
||||
}
|
||||
if (localFonts.includes(family.name)) {
|
||||
return null;
|
||||
}
|
||||
const localFontsMappings = localFonts.map((font) => ({
|
||||
font,
|
||||
// We mustn't wrap in quote because that's handled by the CSS renderer
|
||||
name: `${family.uniqueName} fallback: ${font}`
|
||||
}));
|
||||
fallbacks = [...localFontsMappings.map((m) => m.name), ...fallbacks];
|
||||
let css = "";
|
||||
for (const { font, name } of localFontsMappings) {
|
||||
for (const collected of collectedFonts) {
|
||||
css += fontMetricsResolver.generateFontFace({
|
||||
metrics: await fontMetricsResolver.getMetrics(family.name, collected),
|
||||
fallbackMetrics: systemFallbacksProvider.getMetricsForLocalFont(font),
|
||||
font,
|
||||
name,
|
||||
properties: unifontFontFaceDataToProperties(collected.data)
|
||||
});
|
||||
}
|
||||
}
|
||||
return { css, fallbacks };
|
||||
}
|
||||
export {
|
||||
optimizeFallbacks
|
||||
};
|
||||
6
node_modules/astro/dist/assets/fonts/core/resolve-family.d.ts
generated
vendored
Normal file
6
node_modules/astro/dist/assets/fonts/core/resolve-family.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { Hasher } from '../definitions.js';
|
||||
import type { FontFamily, ResolvedFontFamily } from '../types.js';
|
||||
export declare function resolveFamily({ family, hasher, }: {
|
||||
family: FontFamily;
|
||||
hasher: Hasher;
|
||||
}): ResolvedFontFamily;
|
||||
23
node_modules/astro/dist/assets/fonts/core/resolve-family.js
generated
vendored
Normal file
23
node_modules/astro/dist/assets/fonts/core/resolve-family.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
import { dedupe, withoutQuotes } from "../utils.js";
|
||||
function resolveFamily({
|
||||
family,
|
||||
hasher
|
||||
}) {
|
||||
const name = withoutQuotes(family.name);
|
||||
return {
|
||||
...family,
|
||||
name,
|
||||
// This will be used in CSS font faces. Quotes are added by the CSS renderer if
|
||||
// this value contains a space.
|
||||
uniqueName: `${name}-${hasher.hashObject(family)}`,
|
||||
weights: family.weights ? dedupe(family.weights.map((weight) => weight.toString())) : void 0,
|
||||
styles: family.styles ? dedupe(family.styles) : void 0,
|
||||
subsets: family.subsets ? dedupe(family.subsets) : void 0,
|
||||
formats: family.formats ? dedupe(family.formats) : void 0,
|
||||
fallbacks: family.fallbacks ? dedupe(family.fallbacks) : void 0,
|
||||
unicodeRange: family.unicodeRange ? dedupe(family.unicodeRange) : void 0
|
||||
};
|
||||
}
|
||||
export {
|
||||
resolveFamily
|
||||
};
|
||||
72
node_modules/astro/dist/assets/fonts/definitions.d.ts
generated
vendored
Normal file
72
node_modules/astro/dist/assets/fonts/definitions.d.ts
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
import type * as unifont from 'unifont';
|
||||
import type { CollectedFontForMetrics } from './core/optimize-fallbacks.js';
|
||||
import type { CssProperties, FontFaceMetrics, FontFileData, FontProvider, FontType, GenericFallbackName, ResolveFontOptions, Style } from './types.js';
|
||||
export interface Hasher {
|
||||
hashString: (input: string) => string;
|
||||
hashObject: (input: Record<string, any>) => string;
|
||||
}
|
||||
export interface UrlResolver {
|
||||
resolve: (id: string) => string;
|
||||
readonly cspResources: Array<string>;
|
||||
}
|
||||
export interface FontFileContentResolver {
|
||||
resolve: (url: string) => string;
|
||||
}
|
||||
export interface CssRenderer {
|
||||
generateFontFace: (family: string, properties: CssProperties) => string;
|
||||
generateCssVariable: (key: string, values: Array<string>) => string;
|
||||
}
|
||||
export interface FontMetricsResolver {
|
||||
getMetrics: (name: string, font: CollectedFontForMetrics) => Promise<FontFaceMetrics>;
|
||||
generateFontFace: (input: {
|
||||
metrics: FontFaceMetrics;
|
||||
fallbackMetrics: FontFaceMetrics;
|
||||
name: string;
|
||||
font: string;
|
||||
properties: CssProperties;
|
||||
}) => string;
|
||||
}
|
||||
export interface SystemFallbacksProvider {
|
||||
getLocalFonts: (fallback: GenericFallbackName) => Array<string> | null;
|
||||
getMetricsForLocalFont: (family: string) => FontFaceMetrics;
|
||||
}
|
||||
export interface FontFetcher {
|
||||
fetch: (input: FontFileData) => Promise<Buffer>;
|
||||
}
|
||||
export interface FontTypeExtractor {
|
||||
extract: (url: string) => FontType;
|
||||
}
|
||||
export interface FontFileReader {
|
||||
extract: (input: {
|
||||
family: string;
|
||||
url: string;
|
||||
}) => {
|
||||
weight: string;
|
||||
style: Style;
|
||||
};
|
||||
}
|
||||
export interface FontFileIdGenerator {
|
||||
generate: (input: {
|
||||
originalUrl: string;
|
||||
type: FontType;
|
||||
cssVariable: string;
|
||||
font: unifont.FontFaceData;
|
||||
}) => string;
|
||||
}
|
||||
export interface StringMatcher {
|
||||
getClosestMatch: (target: string, candidates: Array<string>) => string;
|
||||
}
|
||||
export interface Storage {
|
||||
getItem: (key: string) => Promise<any | null>;
|
||||
getItemRaw: (key: string) => Promise<Buffer | null>;
|
||||
setItem: (key: string, value: any) => Promise<void>;
|
||||
setItemRaw: (key: string, value: any) => Promise<void>;
|
||||
}
|
||||
export interface FontResolver {
|
||||
resolveFont: (options: ResolveFontOptions<Record<string, any>> & {
|
||||
provider: FontProvider;
|
||||
}) => Promise<Array<unifont.FontFaceData>>;
|
||||
listFonts: (options: {
|
||||
provider: FontProvider;
|
||||
}) => Promise<string[] | undefined>;
|
||||
}
|
||||
0
node_modules/astro/dist/assets/fonts/definitions.js
generated
vendored
Normal file
0
node_modules/astro/dist/assets/fonts/definitions.js
generated
vendored
Normal file
13
node_modules/astro/dist/assets/fonts/infra/build-font-file-id-generator.d.ts
generated
vendored
Normal file
13
node_modules/astro/dist/assets/fonts/infra/build-font-file-id-generator.d.ts
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import type { FontFileContentResolver, FontFileIdGenerator, Hasher } from '../definitions.js';
|
||||
import type { FontType } from '../types.js';
|
||||
export declare class BuildFontFileIdGenerator implements FontFileIdGenerator {
|
||||
#private;
|
||||
constructor({ hasher, contentResolver, }: {
|
||||
hasher: Hasher;
|
||||
contentResolver: FontFileContentResolver;
|
||||
});
|
||||
generate({ originalUrl, type }: {
|
||||
originalUrl: string;
|
||||
type: FontType;
|
||||
}): string;
|
||||
}
|
||||
17
node_modules/astro/dist/assets/fonts/infra/build-font-file-id-generator.js
generated
vendored
Normal file
17
node_modules/astro/dist/assets/fonts/infra/build-font-file-id-generator.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
class BuildFontFileIdGenerator {
|
||||
#hasher;
|
||||
#contentResolver;
|
||||
constructor({
|
||||
hasher,
|
||||
contentResolver
|
||||
}) {
|
||||
this.#hasher = hasher;
|
||||
this.#contentResolver = contentResolver;
|
||||
}
|
||||
generate({ originalUrl, type }) {
|
||||
return `${this.#hasher.hashString(this.#contentResolver.resolve(originalUrl))}.${type}`;
|
||||
}
|
||||
}
|
||||
export {
|
||||
BuildFontFileIdGenerator
|
||||
};
|
||||
12
node_modules/astro/dist/assets/fonts/infra/build-url-resolver.d.ts
generated
vendored
Normal file
12
node_modules/astro/dist/assets/fonts/infra/build-url-resolver.d.ts
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { AssetsPrefix } from '../../../types/public/index.js';
|
||||
import type { UrlResolver } from '../definitions.js';
|
||||
export declare class BuildUrlResolver implements UrlResolver {
|
||||
#private;
|
||||
constructor({ base, assetsPrefix, searchParams, }: {
|
||||
base: string;
|
||||
assetsPrefix: AssetsPrefix;
|
||||
searchParams: URLSearchParams;
|
||||
});
|
||||
resolve(id: string): string;
|
||||
get cspResources(): Array<string>;
|
||||
}
|
||||
40
node_modules/astro/dist/assets/fonts/infra/build-url-resolver.js
generated
vendored
Normal file
40
node_modules/astro/dist/assets/fonts/infra/build-url-resolver.js
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
import { fileExtension, joinPaths, prependForwardSlash } from "../../../core/path.js";
|
||||
import { getAssetsPrefix } from "../../utils/getAssetsPrefix.js";
|
||||
import { createPlaceholderURL, stringifyPlaceholderURL } from "../../utils/url.js";
|
||||
class BuildUrlResolver {
|
||||
#resources = /* @__PURE__ */ new Set();
|
||||
#base;
|
||||
#assetsPrefix;
|
||||
#searchParams;
|
||||
constructor({
|
||||
base,
|
||||
assetsPrefix,
|
||||
searchParams
|
||||
}) {
|
||||
this.#base = base;
|
||||
this.#assetsPrefix = assetsPrefix;
|
||||
this.#searchParams = searchParams;
|
||||
}
|
||||
resolve(id) {
|
||||
const prefix = this.#assetsPrefix ? getAssetsPrefix(fileExtension(id), this.#assetsPrefix) : void 0;
|
||||
let urlPath;
|
||||
if (prefix) {
|
||||
this.#resources.add(prefix);
|
||||
urlPath = joinPaths(prefix, this.#base, id);
|
||||
} else {
|
||||
this.#resources.add("'self'");
|
||||
urlPath = prependForwardSlash(joinPaths(this.#base, id));
|
||||
}
|
||||
const url = createPlaceholderURL(urlPath);
|
||||
this.#searchParams.forEach((value, key) => {
|
||||
url.searchParams.set(key, value);
|
||||
});
|
||||
return stringifyPlaceholderURL(url);
|
||||
}
|
||||
get cspResources() {
|
||||
return Array.from(this.#resources);
|
||||
}
|
||||
}
|
||||
export {
|
||||
BuildUrlResolver
|
||||
};
|
||||
11
node_modules/astro/dist/assets/fonts/infra/cached-font-fetcher.d.ts
generated
vendored
Normal file
11
node_modules/astro/dist/assets/fonts/infra/cached-font-fetcher.d.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import type { FontFetcher, Storage } from '../definitions.js';
|
||||
import type { FontFileData } from '../types.js';
|
||||
export declare class CachedFontFetcher implements FontFetcher {
|
||||
#private;
|
||||
constructor({ storage, fetch, readFile, }: {
|
||||
storage: Storage;
|
||||
fetch: (url: string, init?: RequestInit) => Promise<Response>;
|
||||
readFile: (url: string) => Promise<Buffer>;
|
||||
});
|
||||
fetch({ id, url, init }: FontFileData): Promise<Buffer>;
|
||||
}
|
||||
50
node_modules/astro/dist/assets/fonts/infra/cached-font-fetcher.js
generated
vendored
Normal file
50
node_modules/astro/dist/assets/fonts/infra/cached-font-fetcher.js
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
import { isAbsolute } from "node:path";
|
||||
import { AstroError, AstroErrorData } from "../../../core/errors/index.js";
|
||||
class CachedFontFetcher {
|
||||
#storage;
|
||||
#fetch;
|
||||
#readFile;
|
||||
constructor({
|
||||
storage,
|
||||
fetch,
|
||||
readFile
|
||||
}) {
|
||||
this.#storage = storage;
|
||||
this.#fetch = fetch;
|
||||
this.#readFile = readFile;
|
||||
}
|
||||
async #cache(storage, key, cb) {
|
||||
const existing = await storage.getItemRaw(key);
|
||||
if (existing) {
|
||||
return existing;
|
||||
}
|
||||
const data = await cb();
|
||||
await storage.setItemRaw(key, data);
|
||||
return data;
|
||||
}
|
||||
async fetch({ id, url, init }) {
|
||||
return await this.#cache(this.#storage, id, async () => {
|
||||
try {
|
||||
if (isAbsolute(url)) {
|
||||
return await this.#readFile(url);
|
||||
}
|
||||
const response = await this.#fetch(url, init ?? void 0);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Response was not successful, received status code ${response.status}`);
|
||||
}
|
||||
return Buffer.from(await response.arrayBuffer());
|
||||
} catch (cause) {
|
||||
throw new AstroError(
|
||||
{
|
||||
...AstroErrorData.CannotFetchFontFile,
|
||||
message: AstroErrorData.CannotFetchFontFile.message(url)
|
||||
},
|
||||
{ cause }
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
export {
|
||||
CachedFontFetcher
|
||||
};
|
||||
18
node_modules/astro/dist/assets/fonts/infra/capsize-font-metrics-resolver.d.ts
generated
vendored
Normal file
18
node_modules/astro/dist/assets/fonts/infra/capsize-font-metrics-resolver.d.ts
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import type { CollectedFontForMetrics } from '../core/optimize-fallbacks.js';
|
||||
import type { CssRenderer, FontFetcher, FontMetricsResolver } from '../definitions.js';
|
||||
import type { CssProperties, FontFaceMetrics } from '../types.js';
|
||||
export declare class CapsizeFontMetricsResolver implements FontMetricsResolver {
|
||||
#private;
|
||||
constructor({ fontFetcher, cssRenderer, }: {
|
||||
fontFetcher: FontFetcher;
|
||||
cssRenderer: CssRenderer;
|
||||
});
|
||||
getMetrics(name: string, font: CollectedFontForMetrics): Promise<FontFaceMetrics>;
|
||||
generateFontFace({ metrics, fallbackMetrics, name: fallbackName, font: fallbackFontName, properties, }: {
|
||||
metrics: FontFaceMetrics;
|
||||
fallbackMetrics: FontFaceMetrics;
|
||||
name: string;
|
||||
font: string;
|
||||
properties: CssProperties;
|
||||
}): string;
|
||||
}
|
||||
71
node_modules/astro/dist/assets/fonts/infra/capsize-font-metrics-resolver.js
generated
vendored
Normal file
71
node_modules/astro/dist/assets/fonts/infra/capsize-font-metrics-resolver.js
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
import { fromBuffer } from "@capsizecss/unpack";
|
||||
import { renderFontSrc } from "../utils.js";
|
||||
function filterRequiredMetrics({
|
||||
ascent,
|
||||
descent,
|
||||
lineGap,
|
||||
unitsPerEm,
|
||||
xWidthAvg
|
||||
}) {
|
||||
return {
|
||||
ascent,
|
||||
descent,
|
||||
lineGap,
|
||||
unitsPerEm,
|
||||
xWidthAvg
|
||||
};
|
||||
}
|
||||
function round(value) {
|
||||
return Number.parseFloat(value.toFixed(4));
|
||||
}
|
||||
function toPercentString(value) {
|
||||
return `${round(value * 100)}%`;
|
||||
}
|
||||
class CapsizeFontMetricsResolver {
|
||||
#cache = {};
|
||||
#fontFetcher;
|
||||
#cssRenderer;
|
||||
constructor({
|
||||
fontFetcher,
|
||||
cssRenderer
|
||||
}) {
|
||||
this.#fontFetcher = fontFetcher;
|
||||
this.#cssRenderer = cssRenderer;
|
||||
}
|
||||
async getMetrics(name, font) {
|
||||
return this.#cache[name] ??= filterRequiredMetrics(
|
||||
await fromBuffer(await this.#fontFetcher.fetch(font))
|
||||
);
|
||||
}
|
||||
// Adapted from Capsize
|
||||
// Source: https://github.com/seek-oss/capsize/blob/b752693428b45994442433f7e3476ca4e3e3c507/packages/core/src/createFontStack.ts
|
||||
generateFontFace({
|
||||
metrics,
|
||||
fallbackMetrics,
|
||||
name: fallbackName,
|
||||
font: fallbackFontName,
|
||||
properties
|
||||
}) {
|
||||
const preferredFontXAvgRatio = metrics.xWidthAvg / metrics.unitsPerEm;
|
||||
const fallbackFontXAvgRatio = fallbackMetrics.xWidthAvg / fallbackMetrics.unitsPerEm;
|
||||
const sizeAdjust = preferredFontXAvgRatio && fallbackFontXAvgRatio ? preferredFontXAvgRatio / fallbackFontXAvgRatio : 1;
|
||||
const adjustedEmSquare = metrics.unitsPerEm * sizeAdjust;
|
||||
const ascentOverride = metrics.ascent / adjustedEmSquare;
|
||||
const descentOverride = Math.abs(metrics.descent) / adjustedEmSquare;
|
||||
const lineGapOverride = metrics.lineGap / adjustedEmSquare;
|
||||
const fallbackAscentOverride = fallbackMetrics.ascent / adjustedEmSquare;
|
||||
const fallbackDescentOverride = Math.abs(fallbackMetrics.descent) / adjustedEmSquare;
|
||||
const fallbackLineGapOverride = fallbackMetrics.lineGap / adjustedEmSquare;
|
||||
return this.#cssRenderer.generateFontFace(fallbackName, {
|
||||
...properties,
|
||||
src: renderFontSrc([{ name: fallbackFontName }]),
|
||||
"size-adjust": sizeAdjust && sizeAdjust !== 1 ? toPercentString(sizeAdjust) : void 0,
|
||||
"ascent-override": ascentOverride && ascentOverride !== fallbackAscentOverride ? toPercentString(ascentOverride) : void 0,
|
||||
"descent-override": descentOverride && descentOverride !== fallbackDescentOverride ? toPercentString(descentOverride) : void 0,
|
||||
"line-gap-override": lineGapOverride !== fallbackLineGapOverride ? toPercentString(lineGapOverride) : void 0
|
||||
});
|
||||
}
|
||||
}
|
||||
export {
|
||||
CapsizeFontMetricsResolver
|
||||
};
|
||||
16
node_modules/astro/dist/assets/fonts/infra/dev-font-file-id-generator.d.ts
generated
vendored
Normal file
16
node_modules/astro/dist/assets/fonts/infra/dev-font-file-id-generator.d.ts
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import type * as unifont from 'unifont';
|
||||
import type { FontFileContentResolver, FontFileIdGenerator, Hasher } from '../definitions.js';
|
||||
import type { FontType } from '../types.js';
|
||||
export declare class DevFontFileIdGenerator implements FontFileIdGenerator {
|
||||
#private;
|
||||
constructor({ hasher, contentResolver, }: {
|
||||
hasher: Hasher;
|
||||
contentResolver: FontFileContentResolver;
|
||||
});
|
||||
generate({ cssVariable, originalUrl, type, font, }: {
|
||||
originalUrl: string;
|
||||
type: FontType;
|
||||
cssVariable: string;
|
||||
font: unifont.FontFaceData;
|
||||
}): string;
|
||||
}
|
||||
40
node_modules/astro/dist/assets/fonts/infra/dev-font-file-id-generator.js
generated
vendored
Normal file
40
node_modules/astro/dist/assets/fonts/infra/dev-font-file-id-generator.js
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
class DevFontFileIdGenerator {
|
||||
#hasher;
|
||||
#contentResolver;
|
||||
constructor({
|
||||
hasher,
|
||||
contentResolver
|
||||
}) {
|
||||
this.#hasher = hasher;
|
||||
this.#contentResolver = contentResolver;
|
||||
}
|
||||
#formatWeight(weight) {
|
||||
if (Array.isArray(weight)) {
|
||||
return weight.join("-");
|
||||
}
|
||||
if (typeof weight === "number") {
|
||||
return weight.toString();
|
||||
}
|
||||
return weight?.replace(/\s+/g, "-");
|
||||
}
|
||||
#formatStyle(style) {
|
||||
return style?.replace(/\s+/g, "-");
|
||||
}
|
||||
generate({
|
||||
cssVariable,
|
||||
originalUrl,
|
||||
type,
|
||||
font
|
||||
}) {
|
||||
return [
|
||||
cssVariable.slice(2),
|
||||
this.#formatWeight(font.weight),
|
||||
this.#formatStyle(font.style),
|
||||
font.meta?.subset,
|
||||
`${this.#hasher.hashString(this.#contentResolver.resolve(originalUrl))}.${type}`
|
||||
].filter(Boolean).join("-");
|
||||
}
|
||||
}
|
||||
export {
|
||||
DevFontFileIdGenerator
|
||||
};
|
||||
10
node_modules/astro/dist/assets/fonts/infra/dev-url-resolver.d.ts
generated
vendored
Normal file
10
node_modules/astro/dist/assets/fonts/infra/dev-url-resolver.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { UrlResolver } from '../definitions.js';
|
||||
export declare class DevUrlResolver implements UrlResolver {
|
||||
#private;
|
||||
constructor({ base, searchParams, }: {
|
||||
base: string;
|
||||
searchParams: URLSearchParams;
|
||||
});
|
||||
resolve(id: string): string;
|
||||
get cspResources(): Array<string>;
|
||||
}
|
||||
29
node_modules/astro/dist/assets/fonts/infra/dev-url-resolver.js
generated
vendored
Normal file
29
node_modules/astro/dist/assets/fonts/infra/dev-url-resolver.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
import { joinPaths, prependForwardSlash } from "../../../core/path.js";
|
||||
import { createPlaceholderURL, stringifyPlaceholderURL } from "../../utils/url.js";
|
||||
class DevUrlResolver {
|
||||
#resolved = false;
|
||||
#base;
|
||||
#searchParams;
|
||||
constructor({
|
||||
base,
|
||||
searchParams
|
||||
}) {
|
||||
this.#base = base;
|
||||
this.#searchParams = searchParams;
|
||||
}
|
||||
resolve(id) {
|
||||
this.#resolved ||= true;
|
||||
const urlPath = prependForwardSlash(joinPaths(this.#base, id));
|
||||
const url = createPlaceholderURL(urlPath);
|
||||
this.#searchParams.forEach((value, key) => {
|
||||
url.searchParams.set(key, value);
|
||||
});
|
||||
return stringifyPlaceholderURL(url);
|
||||
}
|
||||
get cspResources() {
|
||||
return this.#resolved ? ["'self'"] : [];
|
||||
}
|
||||
}
|
||||
export {
|
||||
DevUrlResolver
|
||||
};
|
||||
11
node_modules/astro/dist/assets/fonts/infra/fontace-font-file-reader.d.ts
generated
vendored
Normal file
11
node_modules/astro/dist/assets/fonts/infra/fontace-font-file-reader.d.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import type { FontFileReader } from '../definitions.js';
|
||||
import type { Style } from '../types.js';
|
||||
export declare class FontaceFontFileReader implements FontFileReader {
|
||||
extract({ family, url }: {
|
||||
family: string;
|
||||
url: string;
|
||||
}): {
|
||||
weight: string;
|
||||
style: Style;
|
||||
};
|
||||
}
|
||||
25
node_modules/astro/dist/assets/fonts/infra/fontace-font-file-reader.js
generated
vendored
Normal file
25
node_modules/astro/dist/assets/fonts/infra/fontace-font-file-reader.js
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { fontace } from "fontace";
|
||||
import { AstroError, AstroErrorData } from "../../../core/errors/index.js";
|
||||
class FontaceFontFileReader {
|
||||
extract({ family, url }) {
|
||||
try {
|
||||
const data = fontace(readFileSync(url));
|
||||
return {
|
||||
weight: data.weight,
|
||||
style: data.style
|
||||
};
|
||||
} catch (cause) {
|
||||
throw new AstroError(
|
||||
{
|
||||
...AstroErrorData.CannotDetermineWeightAndStyleFromFontFile,
|
||||
message: AstroErrorData.CannotDetermineWeightAndStyleFromFontFile.message(family, url)
|
||||
},
|
||||
{ cause }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
export {
|
||||
FontaceFontFileReader
|
||||
};
|
||||
10
node_modules/astro/dist/assets/fonts/infra/fs-font-file-content-resolver.d.ts
generated
vendored
Normal file
10
node_modules/astro/dist/assets/fonts/infra/fs-font-file-content-resolver.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { FontFileContentResolver } from '../definitions.js';
|
||||
type ReadFileSync = (path: string) => string;
|
||||
export declare class FsFontFileContentResolver implements FontFileContentResolver {
|
||||
#private;
|
||||
constructor({ readFileSync }: {
|
||||
readFileSync: ReadFileSync;
|
||||
});
|
||||
resolve(url: string): string;
|
||||
}
|
||||
export {};
|
||||
21
node_modules/astro/dist/assets/fonts/infra/fs-font-file-content-resolver.js
generated
vendored
Normal file
21
node_modules/astro/dist/assets/fonts/infra/fs-font-file-content-resolver.js
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import { isAbsolute } from "node:path";
|
||||
import { AstroError, AstroErrorData } from "../../../core/errors/index.js";
|
||||
class FsFontFileContentResolver {
|
||||
#readFileSync;
|
||||
constructor({ readFileSync }) {
|
||||
this.#readFileSync = readFileSync;
|
||||
}
|
||||
resolve(url) {
|
||||
if (!isAbsolute(url)) {
|
||||
return url;
|
||||
}
|
||||
try {
|
||||
return url + this.#readFileSync(url);
|
||||
} catch (cause) {
|
||||
throw new AstroError(AstroErrorData.UnknownFilesystemError, { cause });
|
||||
}
|
||||
}
|
||||
}
|
||||
export {
|
||||
FsFontFileContentResolver
|
||||
};
|
||||
5
node_modules/astro/dist/assets/fonts/infra/levenshtein-string-matcher.d.ts
generated
vendored
Normal file
5
node_modules/astro/dist/assets/fonts/infra/levenshtein-string-matcher.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { StringMatcher } from '../definitions.js';
|
||||
export declare class LevenshteinStringMatcher implements StringMatcher {
|
||||
#private;
|
||||
getClosestMatch(target: string, candidates: Array<string>): string;
|
||||
}
|
||||
145
node_modules/astro/dist/assets/fonts/infra/levenshtein-string-matcher.js
generated
vendored
Normal file
145
node_modules/astro/dist/assets/fonts/infra/levenshtein-string-matcher.js
generated
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
class LevenshteinStringMatcher {
|
||||
#peq = new Uint32Array(65536);
|
||||
#myers_32(a, b) {
|
||||
const n = a.length;
|
||||
const m = b.length;
|
||||
const lst = 1 << n - 1;
|
||||
let pv = -1;
|
||||
let mv = 0;
|
||||
let sc = n;
|
||||
let i = n;
|
||||
while (i--) {
|
||||
this.#peq[a.charCodeAt(i)] |= 1 << i;
|
||||
}
|
||||
for (i = 0; i < m; i++) {
|
||||
let eq = this.#peq[b.charCodeAt(i)];
|
||||
const xv = eq | mv;
|
||||
eq |= (eq & pv) + pv ^ pv;
|
||||
mv |= ~(eq | pv);
|
||||
pv &= eq;
|
||||
if (mv & lst) {
|
||||
sc++;
|
||||
}
|
||||
if (pv & lst) {
|
||||
sc--;
|
||||
}
|
||||
mv = mv << 1 | 1;
|
||||
pv = pv << 1 | ~(xv | mv);
|
||||
mv &= xv;
|
||||
}
|
||||
i = n;
|
||||
while (i--) {
|
||||
this.#peq[a.charCodeAt(i)] = 0;
|
||||
}
|
||||
return sc;
|
||||
}
|
||||
#myers_x(b, a) {
|
||||
const n = a.length;
|
||||
const m = b.length;
|
||||
const mhc = [];
|
||||
const phc = [];
|
||||
const hsize = Math.ceil(n / 32);
|
||||
const vsize = Math.ceil(m / 32);
|
||||
for (let i = 0; i < hsize; i++) {
|
||||
phc[i] = -1;
|
||||
mhc[i] = 0;
|
||||
}
|
||||
let j = 0;
|
||||
for (; j < vsize - 1; j++) {
|
||||
let mv2 = 0;
|
||||
let pv2 = -1;
|
||||
const start2 = j * 32;
|
||||
const vlen2 = Math.min(32, m) + start2;
|
||||
for (let k = start2; k < vlen2; k++) {
|
||||
this.#peq[b.charCodeAt(k)] |= 1 << k;
|
||||
}
|
||||
for (let i = 0; i < n; i++) {
|
||||
const eq = this.#peq[a.charCodeAt(i)];
|
||||
const pb = phc[i / 32 | 0] >>> i & 1;
|
||||
const mb = mhc[i / 32 | 0] >>> i & 1;
|
||||
const xv = eq | mv2;
|
||||
const xh = ((eq | mb) & pv2) + pv2 ^ pv2 | eq | mb;
|
||||
let ph = mv2 | ~(xh | pv2);
|
||||
let mh = pv2 & xh;
|
||||
if (ph >>> 31 ^ pb) {
|
||||
phc[i / 32 | 0] ^= 1 << i;
|
||||
}
|
||||
if (mh >>> 31 ^ mb) {
|
||||
mhc[i / 32 | 0] ^= 1 << i;
|
||||
}
|
||||
ph = ph << 1 | pb;
|
||||
mh = mh << 1 | mb;
|
||||
pv2 = mh | ~(xv | ph);
|
||||
mv2 = ph & xv;
|
||||
}
|
||||
for (let k = start2; k < vlen2; k++) {
|
||||
this.#peq[b.charCodeAt(k)] = 0;
|
||||
}
|
||||
}
|
||||
let mv = 0;
|
||||
let pv = -1;
|
||||
const start = j * 32;
|
||||
const vlen = Math.min(32, m - start) + start;
|
||||
for (let k = start; k < vlen; k++) {
|
||||
this.#peq[b.charCodeAt(k)] |= 1 << k;
|
||||
}
|
||||
let score = m;
|
||||
for (let i = 0; i < n; i++) {
|
||||
const eq = this.#peq[a.charCodeAt(i)];
|
||||
const pb = phc[i / 32 | 0] >>> i & 1;
|
||||
const mb = mhc[i / 32 | 0] >>> i & 1;
|
||||
const xv = eq | mv;
|
||||
const xh = ((eq | mb) & pv) + pv ^ pv | eq | mb;
|
||||
let ph = mv | ~(xh | pv);
|
||||
let mh = pv & xh;
|
||||
score += ph >>> m - 1 & 1;
|
||||
score -= mh >>> m - 1 & 1;
|
||||
if (ph >>> 31 ^ pb) {
|
||||
phc[i / 32 | 0] ^= 1 << i;
|
||||
}
|
||||
if (mh >>> 31 ^ mb) {
|
||||
mhc[i / 32 | 0] ^= 1 << i;
|
||||
}
|
||||
ph = ph << 1 | pb;
|
||||
mh = mh << 1 | mb;
|
||||
pv = mh | ~(xv | ph);
|
||||
mv = ph & xv;
|
||||
}
|
||||
for (let k = start; k < vlen; k++) {
|
||||
this.#peq[b.charCodeAt(k)] = 0;
|
||||
}
|
||||
return score;
|
||||
}
|
||||
#distance(a, b) {
|
||||
if (a.length < b.length) {
|
||||
const tmp = b;
|
||||
b = a;
|
||||
a = tmp;
|
||||
}
|
||||
if (b.length === 0) {
|
||||
return a.length;
|
||||
}
|
||||
if (a.length <= 32) {
|
||||
return this.#myers_32(a, b);
|
||||
}
|
||||
return this.#myers_x(a, b);
|
||||
}
|
||||
#closest(str, arr) {
|
||||
let min_distance = Number.POSITIVE_INFINITY;
|
||||
let min_index = 0;
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
const dist = this.#distance(str, arr[i]);
|
||||
if (dist < min_distance) {
|
||||
min_distance = dist;
|
||||
min_index = i;
|
||||
}
|
||||
}
|
||||
return arr[min_index];
|
||||
}
|
||||
getClosestMatch(target, candidates) {
|
||||
return this.#closest(target, candidates);
|
||||
}
|
||||
}
|
||||
export {
|
||||
LevenshteinStringMatcher
|
||||
};
|
||||
15
node_modules/astro/dist/assets/fonts/infra/minifiable-css-renderer.d.ts
generated
vendored
Normal file
15
node_modules/astro/dist/assets/fonts/infra/minifiable-css-renderer.d.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import type { CssRenderer } from '../definitions.js';
|
||||
import type { CssProperties } from '../types.js';
|
||||
export declare function renderFontFace(properties: CssProperties, minify: boolean): string;
|
||||
export declare function renderCssVariable(key: string, values: Array<string>, minify: boolean): string;
|
||||
export declare function withFamily(family: string, properties: CssProperties): CssProperties;
|
||||
/** If the value contains spaces (which would be incorrectly interpreted), we wrap it in quotes. */
|
||||
export declare function handleValueWithSpaces(value: string): string;
|
||||
export declare class MinifiableCssRenderer implements CssRenderer {
|
||||
#private;
|
||||
constructor({ minify }: {
|
||||
minify: boolean;
|
||||
});
|
||||
generateFontFace(family: string, properties: CssProperties): string;
|
||||
generateCssVariable(key: string, values: Array<string>): string;
|
||||
}
|
||||
44
node_modules/astro/dist/assets/fonts/infra/minifiable-css-renderer.js
generated
vendored
Normal file
44
node_modules/astro/dist/assets/fonts/infra/minifiable-css-renderer.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
function renderFontFace(properties, minify) {
|
||||
const lf = minify ? "" : `
|
||||
`;
|
||||
const sp = minify ? "" : " ";
|
||||
return `@font-face${sp}{${lf}${Object.entries(properties).filter(([, value]) => Boolean(value)).map(([key, value]) => `${sp}${sp}${key}:${sp}${value};`).join(lf)}${lf}}${lf}`;
|
||||
}
|
||||
function renderCssVariable(key, values, minify) {
|
||||
const lf = minify ? "" : `
|
||||
`;
|
||||
const sp = minify ? "" : " ";
|
||||
return `:root${sp}{${lf}${sp}${sp}${key}:${sp}${values.map((v) => handleValueWithSpaces(v)).join(`,${sp}`)};${lf}}${lf}`;
|
||||
}
|
||||
function withFamily(family, properties) {
|
||||
return {
|
||||
"font-family": handleValueWithSpaces(family),
|
||||
...properties
|
||||
};
|
||||
}
|
||||
const SPACE_RE = /\s/;
|
||||
function handleValueWithSpaces(value) {
|
||||
if (SPACE_RE.test(value)) {
|
||||
return JSON.stringify(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
class MinifiableCssRenderer {
|
||||
#minify;
|
||||
constructor({ minify }) {
|
||||
this.#minify = minify;
|
||||
}
|
||||
generateFontFace(family, properties) {
|
||||
return renderFontFace(withFamily(family, properties), this.#minify);
|
||||
}
|
||||
generateCssVariable(key, values) {
|
||||
return renderCssVariable(key, values, this.#minify);
|
||||
}
|
||||
}
|
||||
export {
|
||||
MinifiableCssRenderer,
|
||||
handleValueWithSpaces,
|
||||
renderCssVariable,
|
||||
renderFontFace,
|
||||
withFamily
|
||||
};
|
||||
5
node_modules/astro/dist/assets/fonts/infra/node-font-type-extractor.d.ts
generated
vendored
Normal file
5
node_modules/astro/dist/assets/fonts/infra/node-font-type-extractor.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { FontTypeExtractor } from '../definitions.js';
|
||||
import type { FontType } from '../types.js';
|
||||
export declare class NodeFontTypeExtractor implements FontTypeExtractor {
|
||||
extract(url: string): FontType;
|
||||
}
|
||||
21
node_modules/astro/dist/assets/fonts/infra/node-font-type-extractor.js
generated
vendored
Normal file
21
node_modules/astro/dist/assets/fonts/infra/node-font-type-extractor.js
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import { extname } from "node:path";
|
||||
import { AstroError, AstroErrorData } from "../../../core/errors/index.js";
|
||||
import { isFontType } from "../utils.js";
|
||||
class NodeFontTypeExtractor {
|
||||
extract(url) {
|
||||
const extension = extname(url).slice(1);
|
||||
if (!isFontType(extension)) {
|
||||
throw new AstroError(
|
||||
{
|
||||
...AstroErrorData.CannotExtractFontType,
|
||||
message: AstroErrorData.CannotExtractFontType.message(url)
|
||||
},
|
||||
{ cause: `Unexpected extension, got "${extension}"` }
|
||||
);
|
||||
}
|
||||
return extension;
|
||||
}
|
||||
}
|
||||
export {
|
||||
NodeFontTypeExtractor
|
||||
};
|
||||
6
node_modules/astro/dist/assets/fonts/infra/system-fallbacks-provider.d.ts
generated
vendored
Normal file
6
node_modules/astro/dist/assets/fonts/infra/system-fallbacks-provider.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import type { SystemFallbacksProvider } from '../definitions.js';
|
||||
import type { FontFaceMetrics, GenericFallbackName } from '../types.js';
|
||||
export declare class RealSystemFallbacksProvider implements SystemFallbacksProvider {
|
||||
getLocalFonts(fallback: GenericFallbackName): Array<string> | null;
|
||||
getMetricsForLocalFont(family: string): FontFaceMetrics;
|
||||
}
|
||||
71
node_modules/astro/dist/assets/fonts/infra/system-fallbacks-provider.js
generated
vendored
Normal file
71
node_modules/astro/dist/assets/fonts/infra/system-fallbacks-provider.js
generated
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
const SYSTEM_METRICS = {
|
||||
"Times New Roman": {
|
||||
ascent: 1825,
|
||||
descent: -443,
|
||||
lineGap: 87,
|
||||
unitsPerEm: 2048,
|
||||
xWidthAvg: 832
|
||||
},
|
||||
Arial: {
|
||||
ascent: 1854,
|
||||
descent: -434,
|
||||
lineGap: 67,
|
||||
unitsPerEm: 2048,
|
||||
xWidthAvg: 913
|
||||
},
|
||||
"Courier New": {
|
||||
ascent: 1705,
|
||||
descent: -615,
|
||||
lineGap: 0,
|
||||
unitsPerEm: 2048,
|
||||
xWidthAvg: 1229
|
||||
},
|
||||
BlinkMacSystemFont: {
|
||||
ascent: 1980,
|
||||
descent: -432,
|
||||
lineGap: 0,
|
||||
unitsPerEm: 2048,
|
||||
xWidthAvg: 853
|
||||
},
|
||||
"Segoe UI": {
|
||||
ascent: 2210,
|
||||
descent: -514,
|
||||
lineGap: 0,
|
||||
unitsPerEm: 2048,
|
||||
xWidthAvg: 908
|
||||
},
|
||||
Roboto: {
|
||||
ascent: 1900,
|
||||
descent: -500,
|
||||
lineGap: 0,
|
||||
unitsPerEm: 2048,
|
||||
xWidthAvg: 911
|
||||
},
|
||||
"Helvetica Neue": {
|
||||
ascent: 952,
|
||||
descent: -213,
|
||||
lineGap: 28,
|
||||
unitsPerEm: 1e3,
|
||||
xWidthAvg: 450
|
||||
}
|
||||
};
|
||||
const DEFAULT_FALLBACKS = {
|
||||
serif: ["Times New Roman"],
|
||||
"sans-serif": ["Arial"],
|
||||
monospace: ["Courier New"],
|
||||
"system-ui": ["BlinkMacSystemFont", "Segoe UI", "Roboto", "Helvetica Neue", "Arial"],
|
||||
"ui-serif": ["Times New Roman"],
|
||||
"ui-sans-serif": ["Arial"],
|
||||
"ui-monospace": ["Courier New"]
|
||||
};
|
||||
class RealSystemFallbacksProvider {
|
||||
getLocalFonts(fallback) {
|
||||
return DEFAULT_FALLBACKS[fallback] ?? null;
|
||||
}
|
||||
getMetricsForLocalFont(family) {
|
||||
return SYSTEM_METRICS[family];
|
||||
}
|
||||
}
|
||||
export {
|
||||
RealSystemFallbacksProvider
|
||||
};
|
||||
34
node_modules/astro/dist/assets/fonts/infra/unifont-font-resolver.d.ts
generated
vendored
Normal file
34
node_modules/astro/dist/assets/fonts/infra/unifont-font-resolver.d.ts
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
import type { FontFaceData, Provider } from 'unifont';
|
||||
import type { FontResolver, Hasher, Storage } from '../definitions.js';
|
||||
import type { FontProvider, ResolvedFontFamily, ResolveFontOptions } from '../types.js';
|
||||
type NonEmptyProviders = [
|
||||
Provider<string, Record<string, any>>,
|
||||
...Array<Provider<string, Record<string, any>>>
|
||||
];
|
||||
export declare class UnifontFontResolver implements FontResolver {
|
||||
#private;
|
||||
private constructor();
|
||||
static idFromProvider({ hasher, provider }: {
|
||||
hasher: Hasher;
|
||||
provider: FontProvider;
|
||||
}): string;
|
||||
static astroToUnifontProvider(astroProvider: FontProvider, root: URL): Provider;
|
||||
static extractUnifontProviders({ families, hasher, root, }: {
|
||||
families: Array<ResolvedFontFamily>;
|
||||
hasher: Hasher;
|
||||
root: URL;
|
||||
}): NonEmptyProviders;
|
||||
static create({ families, hasher, storage, root, }: {
|
||||
families: Array<ResolvedFontFamily>;
|
||||
hasher: Hasher;
|
||||
storage: Storage;
|
||||
root: URL;
|
||||
}): Promise<UnifontFontResolver>;
|
||||
resolveFont({ familyName, provider, options, ...rest }: ResolveFontOptions<Record<string, any>> & {
|
||||
provider: FontProvider;
|
||||
}): Promise<Array<FontFaceData>>;
|
||||
listFonts({ provider }: {
|
||||
provider: FontProvider;
|
||||
}): Promise<string[] | undefined>;
|
||||
}
|
||||
export {};
|
||||
98
node_modules/astro/dist/assets/fonts/infra/unifont-font-resolver.js
generated
vendored
Normal file
98
node_modules/astro/dist/assets/fonts/infra/unifont-font-resolver.js
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
import { createUnifont, defineFontProvider } from "unifont";
|
||||
class UnifontFontResolver {
|
||||
#unifont;
|
||||
#hasher;
|
||||
constructor({
|
||||
unifont,
|
||||
hasher
|
||||
}) {
|
||||
this.#unifont = unifont;
|
||||
this.#hasher = hasher;
|
||||
}
|
||||
static idFromProvider({ hasher, provider }) {
|
||||
const hash = hasher.hashObject({
|
||||
name: provider.name,
|
||||
...provider.config
|
||||
});
|
||||
return `${provider.name}-${hash}`;
|
||||
}
|
||||
static astroToUnifontProvider(astroProvider, root) {
|
||||
return defineFontProvider(astroProvider.name, async (_options, ctx) => {
|
||||
await astroProvider?.init?.({ ...ctx, root });
|
||||
return {
|
||||
async resolveFont(familyName, { options, ...rest }) {
|
||||
return await astroProvider.resolveFont({ familyName, options, ...rest });
|
||||
},
|
||||
async listFonts() {
|
||||
return astroProvider.listFonts?.();
|
||||
}
|
||||
};
|
||||
})(astroProvider.config);
|
||||
}
|
||||
static extractUnifontProviders({
|
||||
families,
|
||||
hasher,
|
||||
root
|
||||
}) {
|
||||
const providers = /* @__PURE__ */ new Map();
|
||||
for (const { provider } of families) {
|
||||
const id = this.idFromProvider({ hasher, provider });
|
||||
if (!providers.has(id)) {
|
||||
const unifontProvider = this.astroToUnifontProvider(provider, root);
|
||||
unifontProvider._name = this.idFromProvider({ hasher, provider });
|
||||
providers.set(id, unifontProvider);
|
||||
}
|
||||
}
|
||||
return Array.from(providers.values());
|
||||
}
|
||||
static async create({
|
||||
families,
|
||||
hasher,
|
||||
storage,
|
||||
root
|
||||
}) {
|
||||
return new UnifontFontResolver({
|
||||
unifont: await createUnifont(this.extractUnifontProviders({ families, hasher, root }), {
|
||||
storage,
|
||||
// TODO: consider enabling, would require new astro errors
|
||||
throwOnError: false
|
||||
}),
|
||||
hasher
|
||||
});
|
||||
}
|
||||
async resolveFont({
|
||||
familyName,
|
||||
provider,
|
||||
options,
|
||||
...rest
|
||||
}) {
|
||||
const id = UnifontFontResolver.idFromProvider({
|
||||
hasher: this.#hasher,
|
||||
provider
|
||||
});
|
||||
const { fonts } = await this.#unifont.resolveFont(
|
||||
familyName,
|
||||
{
|
||||
// Options are currently namespaced by provider name, it may change in
|
||||
// https://github.com/unjs/unifont/pull/287
|
||||
options: {
|
||||
[id]: options
|
||||
},
|
||||
...rest
|
||||
},
|
||||
[id]
|
||||
);
|
||||
return fonts;
|
||||
}
|
||||
async listFonts({ provider }) {
|
||||
return await this.#unifont.listFonts([
|
||||
UnifontFontResolver.idFromProvider({
|
||||
hasher: this.#hasher,
|
||||
provider
|
||||
})
|
||||
]);
|
||||
}
|
||||
}
|
||||
export {
|
||||
UnifontFontResolver
|
||||
};
|
||||
11
node_modules/astro/dist/assets/fonts/infra/unstorage-fs-storage.d.ts
generated
vendored
Normal file
11
node_modules/astro/dist/assets/fonts/infra/unstorage-fs-storage.d.ts
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import type { Storage } from '../definitions.js';
|
||||
export declare class UnstorageFsStorage implements Storage {
|
||||
#private;
|
||||
constructor({ base }: {
|
||||
base: URL;
|
||||
});
|
||||
getItem(key: string): Promise<any | null>;
|
||||
getItemRaw(key: string): Promise<Buffer | null>;
|
||||
setItem(key: string, value: any): Promise<void>;
|
||||
setItemRaw(key: string, value: any): Promise<void>;
|
||||
}
|
||||
26
node_modules/astro/dist/assets/fonts/infra/unstorage-fs-storage.js
generated
vendored
Normal file
26
node_modules/astro/dist/assets/fonts/infra/unstorage-fs-storage.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
import { fileURLToPath } from "node:url";
|
||||
import * as unstorage from "unstorage";
|
||||
import fsLiteDriver from "unstorage/drivers/fs-lite";
|
||||
class UnstorageFsStorage {
|
||||
#unstorage;
|
||||
constructor({ base }) {
|
||||
this.#unstorage = unstorage.createStorage({
|
||||
driver: fsLiteDriver({ base: fileURLToPath(base) })
|
||||
});
|
||||
}
|
||||
async getItem(key) {
|
||||
return await this.#unstorage.getItem(key);
|
||||
}
|
||||
async getItemRaw(key) {
|
||||
return await this.#unstorage.getItemRaw(key);
|
||||
}
|
||||
async setItem(key, value) {
|
||||
return await this.#unstorage.setItem(key, value);
|
||||
}
|
||||
async setItemRaw(key, value) {
|
||||
return await this.#unstorage.setItemRaw(key, value);
|
||||
}
|
||||
}
|
||||
export {
|
||||
UnstorageFsStorage
|
||||
};
|
||||
7
node_modules/astro/dist/assets/fonts/infra/xxhash-hasher.d.ts
generated
vendored
Normal file
7
node_modules/astro/dist/assets/fonts/infra/xxhash-hasher.d.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import type { Hasher } from '../definitions.js';
|
||||
export declare class XxhashHasher implements Hasher {
|
||||
hashString: (input: string) => string;
|
||||
private constructor();
|
||||
static create(): Promise<XxhashHasher>;
|
||||
hashObject(input: Record<string, any>): string;
|
||||
}
|
||||
18
node_modules/astro/dist/assets/fonts/infra/xxhash-hasher.js
generated
vendored
Normal file
18
node_modules/astro/dist/assets/fonts/infra/xxhash-hasher.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import xxhash from "xxhash-wasm";
|
||||
import { sortObjectByKey } from "../utils.js";
|
||||
class XxhashHasher {
|
||||
hashString;
|
||||
constructor(hashString) {
|
||||
this.hashString = hashString;
|
||||
}
|
||||
static async create() {
|
||||
const { h64ToString } = await xxhash();
|
||||
return new XxhashHasher(h64ToString);
|
||||
}
|
||||
hashObject(input) {
|
||||
return this.hashString(JSON.stringify(sortObjectByKey(input)));
|
||||
}
|
||||
}
|
||||
export {
|
||||
XxhashHasher
|
||||
};
|
||||
41
node_modules/astro/dist/assets/fonts/providers/index.d.ts
generated
vendored
Normal file
41
node_modules/astro/dist/assets/fonts/providers/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
import { type AdobeProviderOptions, type GoogleFamilyOptions, type GoogleiconsFamilyOptions, type NpmProviderOptions, type NpmFamilyOptions } from 'unifont';
|
||||
import type { FontProvider } from '../types.js';
|
||||
import { type LocalFamilyOptions } from './local.js';
|
||||
/** [Adobe](https://docs.astro.build/en/reference/font-provider-reference/#adobe) */
|
||||
declare function adobe(config: AdobeProviderOptions): FontProvider;
|
||||
/** [Bunny](https://docs.astro.build/en/reference/font-provider-reference/#bunny) */
|
||||
declare function bunny(): FontProvider;
|
||||
/** [Fontshare](https://docs.astro.build/en/reference/font-provider-reference/#fontshare) */
|
||||
declare function fontshare(): FontProvider;
|
||||
/** [Fontsource](https://docs.astro.build/en/reference/font-provider-reference/#fontsource) */
|
||||
declare function fontsource(): FontProvider;
|
||||
/** [Google](https://docs.astro.build/en/reference/font-provider-reference/#google) */
|
||||
declare function google(): FontProvider<GoogleFamilyOptions | undefined>;
|
||||
/** [Google Icons](https://docs.astro.build/en/reference/font-provider-reference/#google-icons) */
|
||||
declare function googleicons(): FontProvider<GoogleiconsFamilyOptions | undefined>;
|
||||
/** [Local](https://docs.astro.build/en/reference/font-provider-reference/#local) */
|
||||
declare function local(): FontProvider<LocalFamilyOptions>;
|
||||
/** [NPM](https://docs.astro.build/en/reference/font-provider-reference/#npm) */
|
||||
declare function npm(options?: Omit<NpmProviderOptions, 'root' | 'readFile'>): FontProvider<NpmFamilyOptions | undefined>;
|
||||
/**
|
||||
* Astro exports a few built-in providers:
|
||||
* - [Adobe](https://docs.astro.build/en/reference/font-provider-reference/#adobe)
|
||||
* - [Bunny](https://docs.astro.build/en/reference/font-provider-reference/#bunny)
|
||||
* - [Fontshare](https://docs.astro.build/en/reference/font-provider-reference/#fontshare)
|
||||
* - [Fontsource](https://docs.astro.build/en/reference/font-provider-reference/#fontsource)
|
||||
* - [Google](https://docs.astro.build/en/reference/font-provider-reference/#google)
|
||||
* - [Google Icons](https://docs.astro.build/en/reference/font-provider-reference/#google-icons)
|
||||
* - [Local](https://docs.astro.build/en/reference/font-provider-reference/#local)
|
||||
* - [NPM](TODO:)
|
||||
*/
|
||||
export declare const fontProviders: {
|
||||
adobe: typeof adobe;
|
||||
bunny: typeof bunny;
|
||||
fontshare: typeof fontshare;
|
||||
fontsource: typeof fontsource;
|
||||
google: typeof google;
|
||||
googleicons: typeof googleicons;
|
||||
local: typeof local;
|
||||
npm: typeof npm;
|
||||
};
|
||||
export {};
|
||||
141
node_modules/astro/dist/assets/fonts/providers/index.js
generated
vendored
Normal file
141
node_modules/astro/dist/assets/fonts/providers/index.js
generated
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
import {
|
||||
providers
|
||||
} from "unifont";
|
||||
import { FontaceFontFileReader } from "../infra/fontace-font-file-reader.js";
|
||||
import { LocalFontProvider } from "./local.js";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { readFile } from "node:fs/promises";
|
||||
function adobe(config) {
|
||||
const provider = providers.adobe(config);
|
||||
let initializedProvider;
|
||||
return {
|
||||
name: provider._name,
|
||||
config,
|
||||
async init(context) {
|
||||
initializedProvider = await provider(context);
|
||||
},
|
||||
async resolveFont({ familyName, ...rest }) {
|
||||
return await initializedProvider?.resolveFont(familyName, rest);
|
||||
},
|
||||
async listFonts() {
|
||||
return await initializedProvider?.listFonts?.();
|
||||
}
|
||||
};
|
||||
}
|
||||
function bunny() {
|
||||
const provider = providers.bunny();
|
||||
let initializedProvider;
|
||||
return {
|
||||
name: provider._name,
|
||||
async init(context) {
|
||||
initializedProvider = await provider(context);
|
||||
},
|
||||
async resolveFont({ familyName, ...rest }) {
|
||||
return await initializedProvider?.resolveFont(familyName, rest);
|
||||
},
|
||||
async listFonts() {
|
||||
return await initializedProvider?.listFonts?.();
|
||||
}
|
||||
};
|
||||
}
|
||||
function fontshare() {
|
||||
const provider = providers.fontshare();
|
||||
let initializedProvider;
|
||||
return {
|
||||
name: provider._name,
|
||||
async init(context) {
|
||||
initializedProvider = await provider(context);
|
||||
},
|
||||
async resolveFont({ familyName, ...rest }) {
|
||||
return await initializedProvider?.resolveFont(familyName, rest);
|
||||
},
|
||||
async listFonts() {
|
||||
return await initializedProvider?.listFonts?.();
|
||||
}
|
||||
};
|
||||
}
|
||||
function fontsource() {
|
||||
const provider = providers.fontsource();
|
||||
let initializedProvider;
|
||||
return {
|
||||
name: provider._name,
|
||||
async init(context) {
|
||||
initializedProvider = await provider(context);
|
||||
},
|
||||
async resolveFont({ familyName, ...rest }) {
|
||||
return await initializedProvider?.resolveFont(familyName, rest);
|
||||
},
|
||||
async listFonts() {
|
||||
return await initializedProvider?.listFonts?.();
|
||||
}
|
||||
};
|
||||
}
|
||||
function google() {
|
||||
const provider = providers.google();
|
||||
let initializedProvider;
|
||||
return {
|
||||
name: provider._name,
|
||||
async init(context) {
|
||||
initializedProvider = await provider(context);
|
||||
},
|
||||
async resolveFont({ familyName, ...rest }) {
|
||||
return await initializedProvider?.resolveFont(familyName, rest);
|
||||
},
|
||||
async listFonts() {
|
||||
return await initializedProvider?.listFonts?.();
|
||||
}
|
||||
};
|
||||
}
|
||||
function googleicons() {
|
||||
const provider = providers.googleicons();
|
||||
let initializedProvider;
|
||||
return {
|
||||
name: provider._name,
|
||||
async init(context) {
|
||||
initializedProvider = await provider(context);
|
||||
},
|
||||
async resolveFont({ familyName, ...rest }) {
|
||||
return await initializedProvider?.resolveFont(familyName, rest);
|
||||
},
|
||||
async listFonts() {
|
||||
return await initializedProvider?.listFonts?.();
|
||||
}
|
||||
};
|
||||
}
|
||||
function local() {
|
||||
return new LocalFontProvider({
|
||||
fontFileReader: new FontaceFontFileReader()
|
||||
});
|
||||
}
|
||||
function npm(options) {
|
||||
let initializedProvider;
|
||||
return {
|
||||
name: providers.npm()._name,
|
||||
async init(context) {
|
||||
initializedProvider = await providers.npm({
|
||||
...options,
|
||||
root: fileURLToPath(context.root),
|
||||
readFile: (path) => readFile(path, "utf-8").catch(() => null)
|
||||
})(context);
|
||||
},
|
||||
async resolveFont({ familyName, ...rest }) {
|
||||
return await initializedProvider?.resolveFont(familyName, rest);
|
||||
},
|
||||
async listFonts() {
|
||||
return await initializedProvider?.listFonts?.();
|
||||
}
|
||||
};
|
||||
}
|
||||
const fontProviders = {
|
||||
adobe,
|
||||
bunny,
|
||||
fontshare,
|
||||
fontsource,
|
||||
google,
|
||||
googleicons,
|
||||
local,
|
||||
npm
|
||||
};
|
||||
export {
|
||||
fontProviders
|
||||
};
|
||||
57
node_modules/astro/dist/assets/fonts/providers/local.d.ts
generated
vendored
Normal file
57
node_modules/astro/dist/assets/fonts/providers/local.d.ts
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
import type * as unifont from 'unifont';
|
||||
import type { FontFileReader } from '../definitions.js';
|
||||
import type { FamilyProperties, FontProvider, FontProviderInitContext, ResolveFontOptions, Style, Weight } from '../types.js';
|
||||
type RawSource = string | URL | {
|
||||
url: string | URL;
|
||||
tech?: string | undefined;
|
||||
};
|
||||
interface Variant extends FamilyProperties {
|
||||
/**
|
||||
* Font [sources](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src). It can be a path relative to the root, a package import, or a URL. URLs are particularly useful if you inject local fonts through an integration.
|
||||
*
|
||||
* We recommend not putting your font files in [the `public/` directory](/en/reference/configuration-reference/#publicdir). Since Astro will copy these files into that folder at build time, this will result in duplicated files
|
||||
* in your build output. Instead, store them somewhere else in your project, such as in `src/`.
|
||||
*
|
||||
* You can also specify a [tech](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src#tech) by providing objects:
|
||||
*
|
||||
* ```js
|
||||
* src: [{ url:"./src/assets/fonts/MyFont.woff2", tech: "color-COLRv1" }]
|
||||
* ```
|
||||
*/
|
||||
src: [RawSource, ...Array<RawSource>];
|
||||
/**
|
||||
* A [font weight](https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight). If the associated font is a [variable font](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_fonts/Variable_fonts_guide), you can specify a range of weights:
|
||||
*
|
||||
* ```js
|
||||
* weight: "100 900"
|
||||
* ```
|
||||
*
|
||||
* When the value is not set, by default Astro will try to infer the value based on the first source.
|
||||
*/
|
||||
weight?: Weight | undefined;
|
||||
/**
|
||||
* A [font style](https://developer.mozilla.org/en-US/docs/Web/CSS/font-style).
|
||||
*
|
||||
* When the value is not set, by default Astro will try to infer the value based on the first source.
|
||||
*/
|
||||
style?: Style | undefined;
|
||||
}
|
||||
export interface LocalFamilyOptions {
|
||||
/**
|
||||
* The `options.variants` property is required. Each variant represents a [`@font-face` declaration](https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/) and requires a `src`.
|
||||
*/
|
||||
variants: [Variant, ...Array<Variant>];
|
||||
}
|
||||
export declare class LocalFontProvider implements FontProvider<LocalFamilyOptions> {
|
||||
#private;
|
||||
name: string;
|
||||
config?: Record<string, any> | undefined;
|
||||
constructor({ fontFileReader, }: {
|
||||
fontFileReader: FontFileReader;
|
||||
});
|
||||
init(context: Pick<FontProviderInitContext, 'root'>): void;
|
||||
resolveFont(options: ResolveFontOptions<LocalFamilyOptions>): {
|
||||
fonts: Array<unifont.FontFaceData>;
|
||||
};
|
||||
}
|
||||
export {};
|
||||
69
node_modules/astro/dist/assets/fonts/providers/local.js
generated
vendored
Normal file
69
node_modules/astro/dist/assets/fonts/providers/local.js
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
import { createRequire } from "node:module";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
class LocalFontProvider {
|
||||
name = "local";
|
||||
config;
|
||||
#fontFileReader;
|
||||
#root;
|
||||
constructor({
|
||||
fontFileReader
|
||||
}) {
|
||||
this.config = void 0;
|
||||
this.#fontFileReader = fontFileReader;
|
||||
this.#root = void 0;
|
||||
}
|
||||
init(context) {
|
||||
this.#root = context.root;
|
||||
}
|
||||
#resolveEntrypoint(root, entrypoint) {
|
||||
const require2 = createRequire(root);
|
||||
try {
|
||||
return pathToFileURL(require2.resolve(entrypoint));
|
||||
} catch {
|
||||
return new URL(entrypoint, root);
|
||||
}
|
||||
}
|
||||
#normalizeSource(value) {
|
||||
const isValue = typeof value === "string" || value instanceof URL;
|
||||
const url = (isValue ? value : value.url).toString();
|
||||
const tech = isValue ? void 0 : value.tech;
|
||||
return {
|
||||
url: fileURLToPath(this.#resolveEntrypoint(this.#root ?? new URL(import.meta.url), url)),
|
||||
tech
|
||||
};
|
||||
}
|
||||
resolveFont(options) {
|
||||
return {
|
||||
fonts: options.options?.variants.map((variant) => {
|
||||
const shouldInfer = variant.weight === void 0 || variant.style === void 0;
|
||||
const data = {
|
||||
// If it should be inferred, we don't want to set the value
|
||||
weight: variant.weight,
|
||||
style: variant.style,
|
||||
src: [],
|
||||
unicodeRange: variant.unicodeRange,
|
||||
display: variant.display,
|
||||
stretch: variant.stretch,
|
||||
featureSettings: variant.featureSettings,
|
||||
variationSettings: variant.variationSettings
|
||||
};
|
||||
data.src = variant.src.map((rawSource, index) => {
|
||||
const source = this.#normalizeSource(rawSource);
|
||||
if (shouldInfer && index === 0) {
|
||||
const result = this.#fontFileReader.extract({
|
||||
family: options.familyName,
|
||||
url: source.url
|
||||
});
|
||||
if (variant.weight === void 0) data.weight = result.weight;
|
||||
if (variant.style === void 0) data.style = result.style;
|
||||
}
|
||||
return source;
|
||||
});
|
||||
return data;
|
||||
}) ?? []
|
||||
};
|
||||
}
|
||||
}
|
||||
export {
|
||||
LocalFontProvider
|
||||
};
|
||||
1
node_modules/astro/dist/assets/fonts/runtime.d.ts
generated
vendored
Normal file
1
node_modules/astro/dist/assets/fonts/runtime.d.ts
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export declare const fontData: import("./types.js").FontDataByCssVariable;
|
||||
5
node_modules/astro/dist/assets/fonts/runtime.js
generated
vendored
Normal file
5
node_modules/astro/dist/assets/fonts/runtime.js
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import { fontDataByCssVariable } from "virtual:astro:assets/fonts/internal";
|
||||
const fontData = fontDataByCssVariable;
|
||||
export {
|
||||
fontData
|
||||
};
|
||||
2
node_modules/astro/dist/assets/fonts/sync.d.ts
generated
vendored
Normal file
2
node_modules/astro/dist/assets/fonts/sync.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { AstroSettings } from '../../types/astro.js';
|
||||
export declare function syncFonts(settings: AstroSettings): void;
|
||||
17
node_modules/astro/dist/assets/fonts/sync.js
generated
vendored
Normal file
17
node_modules/astro/dist/assets/fonts/sync.js
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import { FONTS_TYPES_FILE } from "./constants.js";
|
||||
function syncFonts(settings) {
|
||||
if (!settings.config.fonts) {
|
||||
return;
|
||||
}
|
||||
settings.injectedTypes.push({
|
||||
filename: FONTS_TYPES_FILE,
|
||||
content: `declare module 'astro:assets' {
|
||||
/** @internal */
|
||||
export type CssVariable = (${JSON.stringify(settings.config.fonts.map((family) => family.cssVariable))})[number];
|
||||
}
|
||||
`
|
||||
});
|
||||
}
|
||||
export {
|
||||
syncFonts
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user