full site update

This commit is contained in:
2025-07-24 18:46:24 +02:00
parent bfe2b90d8d
commit 37a6e0ab31
6912 changed files with 540482 additions and 361712 deletions

View File

@@ -1,10 +1,13 @@
import {
ACTION_QUERY_PARAMS,
ActionError,
appendForwardSlash,
astroCalledServerError,
deserializeActionResult,
getActionQueryString,
} from 'astro:actions';
const apiContextRoutesSymbol = Symbol.for('context.routes');
const ENCODED_DOT = '%2E';
function toActionProxy(actionCallback = {}, aggregatedPath = '') {
@@ -26,10 +29,6 @@ function toActionProxy(actionCallback = {}, aggregatedPath = '') {
// Progressive enhancement info for React.
$$FORM_ACTION: function () {
const searchParams = new URLSearchParams(action.toString());
// Astro will redirect with a GET request by default.
// Disable this behavior to preserve form state
// for React's progressive enhancement.
searchParams.set(ACTION_QUERY_PARAMS.actionRedirect, 'false');
return {
method: 'POST',
// `name` creates a hidden input.
@@ -56,20 +55,33 @@ function toActionProxy(actionCallback = {}, aggregatedPath = '') {
});
}
const SHOULD_APPEND_TRAILING_SLASH = '/** @TRAILING_SLASH@ **/';
/** @param {import('astro:actions').ActionClient<any, any, any>} */
export function getActionPath(action) {
let path = `${import.meta.env.BASE_URL.replace(/\/$/, '')}/_actions/${new URLSearchParams(action.toString()).get(ACTION_QUERY_PARAMS.actionName)}`;
if (SHOULD_APPEND_TRAILING_SLASH) {
path = appendForwardSlash(path);
}
return path;
}
/**
* @param {*} param argument passed to the action when called server or client-side.
* @param {string} path Built path to call action by path name.
* @param {import('../dist/@types/astro.d.ts').APIContext | undefined} context Injected API context when calling actions from the server.
* @param {import('../dist/types/public/context.js').APIContext | undefined} context Injected API context when calling actions from the server.
* Usage: `actions.[name](param)`.
* @returns {Promise<import('../dist/actions/runtime/virtual/shared.js').SafeResult<any, any>>}
*/
async function handleAction(param, path, context) {
// When running server-side, import the action and call it.
if (import.meta.env.SSR) {
const { getAction } = await import('astro/actions/runtime/virtual/get-action.js');
const action = await getAction(path);
if (import.meta.env.SSR && context) {
const pipeline = Reflect.get(context, apiContextRoutesSymbol);
if (!pipeline) {
throw astroCalledServerError();
}
const action = await pipeline.getAction(path);
if (!action) throw new Error(`Action not found: ${path}`);
return action.bind(context)(param);
}
@@ -92,11 +104,19 @@ async function handleAction(param, path, context) {
headers.set('Content-Length', '0');
}
}
const rawResult = await fetch(`${import.meta.env.BASE_URL.replace(/\/$/, '')}/_actions/${path}`, {
method: 'POST',
body,
headers,
});
const rawResult = await fetch(
getActionPath({
toString() {
return getActionQueryString(path);
},
}),
{
method: 'POST',
body,
headers,
},
);
if (rawResult.status === 204) {
return deserializeActionResult({ type: 'empty', status: 204 });
}

View File

@@ -6,12 +6,20 @@ import {
createGetEntries,
createGetEntry,
createGetEntryBySlug,
createGetLiveCollection,
createGetLiveEntry,
createReference,
} from 'astro/content/runtime';
export { defineCollection, renderEntry as render } from 'astro/content/runtime';
export {
defineCollection,
defineLiveCollection,
renderEntry as render,
} from 'astro/content/runtime';
export { z } from 'astro/zod';
/* @@LIVE_CONTENT_CONFIG@@ */
const contentDir = '@@CONTENT_DIR@@';
const contentEntryGlob = '@@CONTENT_ENTRY_GLOB_PATH@@';
@@ -56,25 +64,37 @@ export const getCollection = createGetCollection({
dataCollectionToEntryMap,
getRenderEntryImport: createGlobLookup(collectionToRenderEntryMap),
cacheEntriesByCollection,
});
export const getEntryBySlug = createGetEntryBySlug({
getEntryImport: createGlobLookup(contentCollectionToEntryMap),
getRenderEntryImport: createGlobLookup(collectionToRenderEntryMap),
collectionNames,
});
export const getDataEntryById = createGetDataEntryById({
getEntryImport: createGlobLookup(dataCollectionToEntryMap),
collectionNames,
liveCollections,
});
export const getEntry = createGetEntry({
getEntryImport: createGlobLookup(collectionToEntryMap),
getRenderEntryImport: createGlobLookup(collectionToRenderEntryMap),
collectionNames,
liveCollections,
});
export const getEntryBySlug = createGetEntryBySlug({
getEntryImport: createGlobLookup(contentCollectionToEntryMap),
getRenderEntryImport: createGlobLookup(collectionToRenderEntryMap),
collectionNames,
getEntry,
});
export const getDataEntryById = createGetDataEntryById({
getEntryImport: createGlobLookup(dataCollectionToEntryMap),
collectionNames,
getEntry,
});
export const getEntries = createGetEntries(getEntry);
export const reference = createReference({ lookupMap });
export const getLiveCollection = createGetLiveCollection({
liveCollections,
});
export const getLiveEntry = createGetLiveEntry({
liveCollections,
});

View File

@@ -1,5 +1,5 @@
declare module 'astro:content' {
interface RenderResult {
export interface RenderResult {
Content: import('astro/runtime/server/index.js').AstroComponentFactory;
headings: import('astro').MarkdownHeading[];
remarkPluginFrontmatter: Record<string, any>;
@@ -31,6 +31,25 @@ declare module 'astro:content' {
ContentEntryMap[C]
>['slug'];
export type ReferenceDataEntry<
C extends CollectionKey,
E extends keyof DataEntryMap[C] = string,
> = {
collection: C;
id: E;
};
export type ReferenceContentEntry<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}) = string,
> = {
collection: C;
slug: E;
};
export type ReferenceLiveEntry<C extends keyof LiveContentConfig['collections']> = {
collection: C;
id: string;
};
/** @deprecated Use `getEntry` instead. */
export function getEntryBySlug<
C extends keyof ContentEntryMap,
@@ -58,22 +77,27 @@ declare module 'astro:content' {
filter?: (entry: CollectionEntry<C>) => unknown,
): Promise<CollectionEntry<C>[]>;
export function getLiveCollection<C extends keyof LiveContentConfig['collections']>(
collection: C,
filter?: LiveLoaderCollectionFilterType<C>,
): Promise<
import('astro').LiveDataCollectionResult<LiveLoaderDataType<C>, LiveLoaderErrorType<C>>
>;
export function getEntry<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}),
>(entry: {
collection: C;
slug: E;
}): E extends ValidContentEntrySlug<C>
>(
entry: ReferenceContentEntry<C, E>,
): E extends ValidContentEntrySlug<C>
? Promise<CollectionEntry<C>>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
C extends keyof DataEntryMap,
E extends keyof DataEntryMap[C] | (string & {}),
>(entry: {
collection: C;
id: E;
}): E extends keyof DataEntryMap[C]
>(
entry: ReferenceDataEntry<C, E>,
): E extends keyof DataEntryMap[C]
? Promise<DataEntryMap[C][E]>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
@@ -92,21 +116,21 @@ declare module 'astro:content' {
collection: C,
id: E,
): E extends keyof DataEntryMap[C]
? Promise<DataEntryMap[C][E]>
? string extends keyof DataEntryMap[C]
? Promise<DataEntryMap[C][E]> | undefined
: Promise<DataEntryMap[C][E]>
: Promise<CollectionEntry<C> | undefined>;
export function getLiveEntry<C extends keyof LiveContentConfig['collections']>(
collection: C,
filter: string | LiveLoaderEntryFilterType<C>,
): Promise<import('astro').LiveDataEntryResult<LiveLoaderDataType<C>, LiveLoaderErrorType<C>>>;
/** Resolve an array of entry references from the same collection */
export function getEntries<C extends keyof ContentEntryMap>(
entries: {
collection: C;
slug: ValidContentEntrySlug<C>;
}[],
entries: ReferenceContentEntry<C, ValidContentEntrySlug<C>>[],
): Promise<CollectionEntry<C>[]>;
export function getEntries<C extends keyof DataEntryMap>(
entries: {
collection: C;
id: keyof DataEntryMap[C];
}[],
entries: ReferenceDataEntry<C, keyof DataEntryMap[C]>[],
): Promise<CollectionEntry<C>[]>;
export function render<C extends keyof AnyEntryMap>(
@@ -118,14 +142,8 @@ declare module 'astro:content' {
): import('astro/zod').ZodEffects<
import('astro/zod').ZodString,
C extends keyof ContentEntryMap
? {
collection: C;
slug: ValidContentEntrySlug<C>;
}
: {
collection: C;
id: keyof DataEntryMap[C];
}
? ReferenceContentEntry<C, ValidContentEntrySlug<C>>
: ReferenceDataEntry<C, keyof DataEntryMap[C]>
>;
// Allow generic `string` to avoid excessive type errors in the config
// if `dev` is not running to update as you edit.
@@ -149,5 +167,33 @@ declare module 'astro:content' {
type AnyEntryMap = ContentEntryMap & DataEntryMap;
type ExtractLoaderTypes<T> = T extends import('astro/loaders').LiveLoader<
infer TData,
infer TEntryFilter,
infer TCollectionFilter,
infer TError
>
? { data: TData; entryFilter: TEntryFilter; collectionFilter: TCollectionFilter; error: TError }
: { data: never; entryFilter: never; collectionFilter: never; error: never };
type ExtractDataType<T> = ExtractLoaderTypes<T>['data'];
type ExtractEntryFilterType<T> = ExtractLoaderTypes<T>['entryFilter'];
type ExtractCollectionFilterType<T> = ExtractLoaderTypes<T>['collectionFilter'];
type ExtractErrorType<T> = ExtractLoaderTypes<T>['error'];
type LiveLoaderDataType<C extends keyof LiveContentConfig['collections']> =
LiveContentConfig['collections'][C]['schema'] extends undefined
? ExtractDataType<LiveContentConfig['collections'][C]['loader']>
: import('astro/zod').infer<
Exclude<LiveContentConfig['collections'][C]['schema'], undefined>
>;
type LiveLoaderEntryFilterType<C extends keyof LiveContentConfig['collections']> =
ExtractEntryFilterType<LiveContentConfig['collections'][C]['loader']>;
type LiveLoaderCollectionFilterType<C extends keyof LiveContentConfig['collections']> =
ExtractCollectionFilterType<LiveContentConfig['collections'][C]['loader']>;
type LiveLoaderErrorType<C extends keyof LiveContentConfig['collections']> = ExtractErrorType<
LiveContentConfig['collections'][C]['loader']
>;
export type ContentConfig = '@@CONTENT_CONFIG_TYPE@@';
export type LiveContentConfig = '@@LIVE_CONTENT_CONFIG_TYPE@@';
}

View File

@@ -1,13 +1,24 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
// @ts-check
import { schema } from 'virtual:astro:env/internal';
import {
// biome-ignore lint/correctness/noUnusedImports: `_getEnv` is used by the generated code
getEnv as _getEnv,
createInvalidVariablesError,
getEnv,
getEnvFieldType,
setOnSetGetEnv,
validateEnvVariable,
} from 'astro/env/runtime';
// @ts-expect-error
/** @returns {string} */
// used while generating the virtual module
// biome-ignore lint/correctness/noUnusedFunctionParameters: `key` is used by the generated code
// biome-ignore lint/correctness/noUnusedVariables: `key` is used by the generated code
const getEnv = (key) => {
// @@GET_ENV@@
};
export const getSecret = (key) => {
return getEnv(key);
};
@@ -25,9 +36,6 @@ const _internalGetSecret = (key) => {
throw createInvalidVariablesError(key, type, result);
};
// used while generating the virtual module
// biome-ignore lint/correctness/noUnusedFunctionParameters: `reset` is used by the generated code
// biome-ignore lint/correctness/noUnusedVariables: `reset` is used by the generated code
setOnSetGetEnv((reset) => {
setOnSetGetEnv(() => {
// @@ON_SET_GET_ENV@@
});

View File

@@ -1,9 +0,0 @@
declare module 'astro:env/client' {
// @@CLIENT@@
}
declare module 'astro:env/server' {
// @@SERVER@@
export const getSecret: (key: string) => string | undefined;
}