Refactor routing in App component to enhance navigation and improve error handling by integrating dynamic routes and updating the NotFound route.
This commit is contained in:
110
node_modules/astro/templates/actions.mjs
generated
vendored
Normal file
110
node_modules/astro/templates/actions.mjs
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
import {
|
||||
ACTION_QUERY_PARAMS,
|
||||
ActionError,
|
||||
deserializeActionResult,
|
||||
getActionQueryString,
|
||||
} from 'astro:actions';
|
||||
|
||||
const ENCODED_DOT = '%2E';
|
||||
|
||||
function toActionProxy(actionCallback = {}, aggregatedPath = '') {
|
||||
return new Proxy(actionCallback, {
|
||||
get(target, objKey) {
|
||||
if (objKey in target || typeof objKey === 'symbol') {
|
||||
return target[objKey];
|
||||
}
|
||||
// Add the key, encoding dots so they're not interpreted as nested properties.
|
||||
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,
|
||||
// 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.
|
||||
// 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;
|
||||
},
|
||||
});
|
||||
|
||||
// recurse to construct queries for nested object paths
|
||||
// ex. actions.user.admins.auth()
|
||||
return toActionProxy(action, 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.
|
||||
* 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 (!action) throw new Error(`Action not found: ${path}`);
|
||||
|
||||
return action.bind(context)(param);
|
||||
}
|
||||
|
||||
// When running client-side, make a fetch request to the action path.
|
||||
const headers = new Headers();
|
||||
headers.set('Accept', 'application/json');
|
||||
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(`${import.meta.env.BASE_URL.replace(/\/$/, '')}/_actions/${path}`, {
|
||||
method: 'POST',
|
||||
body,
|
||||
headers,
|
||||
});
|
||||
if (rawResult.status === 204) {
|
||||
return deserializeActionResult({ type: 'empty', status: 204 });
|
||||
}
|
||||
|
||||
return deserializeActionResult({
|
||||
type: rawResult.ok ? 'data' : 'error',
|
||||
body: await rawResult.text(),
|
||||
});
|
||||
}
|
||||
|
||||
export const actions = toActionProxy();
|
80
node_modules/astro/templates/content/module.mjs
generated
vendored
Normal file
80
node_modules/astro/templates/content/module.mjs
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
// astro-head-inject
|
||||
import {
|
||||
createCollectionToGlobResultMap,
|
||||
createGetCollection,
|
||||
createGetDataEntryById,
|
||||
createGetEntries,
|
||||
createGetEntry,
|
||||
createGetEntryBySlug,
|
||||
createReference,
|
||||
} from 'astro/content/runtime';
|
||||
|
||||
export { defineCollection, renderEntry as render } from 'astro/content/runtime';
|
||||
export { z } from 'astro/zod';
|
||||
|
||||
const contentDir = '@@CONTENT_DIR@@';
|
||||
|
||||
const contentEntryGlob = '@@CONTENT_ENTRY_GLOB_PATH@@';
|
||||
const contentCollectionToEntryMap = createCollectionToGlobResultMap({
|
||||
globResult: contentEntryGlob,
|
||||
contentDir,
|
||||
});
|
||||
|
||||
const dataEntryGlob = '@@DATA_ENTRY_GLOB_PATH@@';
|
||||
const dataCollectionToEntryMap = createCollectionToGlobResultMap({
|
||||
globResult: dataEntryGlob,
|
||||
contentDir,
|
||||
});
|
||||
const collectionToEntryMap = createCollectionToGlobResultMap({
|
||||
globResult: { ...contentEntryGlob, ...dataEntryGlob },
|
||||
contentDir,
|
||||
});
|
||||
|
||||
let lookupMap = {};
|
||||
/* @@LOOKUP_MAP_ASSIGNMENT@@ */
|
||||
|
||||
const collectionNames = new Set(Object.keys(lookupMap));
|
||||
|
||||
function createGlobLookup(glob) {
|
||||
return async (collection, lookupId) => {
|
||||
const filePath = lookupMap[collection]?.entries[lookupId];
|
||||
|
||||
if (!filePath) return undefined;
|
||||
return glob[collection][filePath];
|
||||
};
|
||||
}
|
||||
|
||||
const renderEntryGlob = '@@RENDER_ENTRY_GLOB_PATH@@';
|
||||
const collectionToRenderEntryMap = createCollectionToGlobResultMap({
|
||||
globResult: renderEntryGlob,
|
||||
contentDir,
|
||||
});
|
||||
|
||||
const cacheEntriesByCollection = new Map();
|
||||
export const getCollection = createGetCollection({
|
||||
contentCollectionToEntryMap,
|
||||
dataCollectionToEntryMap,
|
||||
getRenderEntryImport: createGlobLookup(collectionToRenderEntryMap),
|
||||
cacheEntriesByCollection,
|
||||
});
|
||||
|
||||
export const getEntryBySlug = createGetEntryBySlug({
|
||||
getEntryImport: createGlobLookup(contentCollectionToEntryMap),
|
||||
getRenderEntryImport: createGlobLookup(collectionToRenderEntryMap),
|
||||
collectionNames,
|
||||
});
|
||||
|
||||
export const getDataEntryById = createGetDataEntryById({
|
||||
getEntryImport: createGlobLookup(dataCollectionToEntryMap),
|
||||
collectionNames,
|
||||
});
|
||||
|
||||
export const getEntry = createGetEntry({
|
||||
getEntryImport: createGlobLookup(collectionToEntryMap),
|
||||
getRenderEntryImport: createGlobLookup(collectionToRenderEntryMap),
|
||||
collectionNames,
|
||||
});
|
||||
|
||||
export const getEntries = createGetEntries(getEntry);
|
||||
|
||||
export const reference = createReference({ lookupMap });
|
153
node_modules/astro/templates/content/types.d.ts
generated
vendored
Normal file
153
node_modules/astro/templates/content/types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
declare module 'astro:content' {
|
||||
interface RenderResult {
|
||||
Content: import('astro/runtime/server/index.js').AstroComponentFactory;
|
||||
headings: import('astro').MarkdownHeading[];
|
||||
remarkPluginFrontmatter: Record<string, any>;
|
||||
}
|
||||
interface Render {
|
||||
'.md': Promise<RenderResult>;
|
||||
}
|
||||
|
||||
export interface RenderedContent {
|
||||
html: string;
|
||||
metadata?: {
|
||||
imagePaths: Array<string>;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
declare module 'astro:content' {
|
||||
type Flatten<T> = T extends { [K: string]: infer U } ? U : never;
|
||||
|
||||
export type CollectionKey = keyof AnyEntryMap;
|
||||
export type CollectionEntry<C extends CollectionKey> = Flatten<AnyEntryMap[C]>;
|
||||
|
||||
export type ContentCollectionKey = keyof ContentEntryMap;
|
||||
export type DataCollectionKey = keyof DataEntryMap;
|
||||
|
||||
type AllValuesOf<T> = T extends any ? T[keyof T] : never;
|
||||
type ValidContentEntrySlug<C extends keyof ContentEntryMap> = AllValuesOf<
|
||||
ContentEntryMap[C]
|
||||
>['slug'];
|
||||
|
||||
/** @deprecated Use `getEntry` instead. */
|
||||
export function getEntryBySlug<
|
||||
C extends keyof ContentEntryMap,
|
||||
E extends ValidContentEntrySlug<C> | (string & {}),
|
||||
>(
|
||||
collection: C,
|
||||
// Note that this has to accept a regular string too, for SSR
|
||||
entrySlug: E,
|
||||
): E extends ValidContentEntrySlug<C>
|
||||
? Promise<CollectionEntry<C>>
|
||||
: Promise<CollectionEntry<C> | undefined>;
|
||||
|
||||
/** @deprecated Use `getEntry` instead. */
|
||||
export function getDataEntryById<C extends keyof DataEntryMap, E extends keyof DataEntryMap[C]>(
|
||||
collection: C,
|
||||
entryId: E,
|
||||
): Promise<CollectionEntry<C>>;
|
||||
|
||||
export function getCollection<C extends keyof AnyEntryMap, E extends CollectionEntry<C>>(
|
||||
collection: C,
|
||||
filter?: (entry: CollectionEntry<C>) => entry is E,
|
||||
): Promise<E[]>;
|
||||
export function getCollection<C extends keyof AnyEntryMap>(
|
||||
collection: C,
|
||||
filter?: (entry: CollectionEntry<C>) => unknown,
|
||||
): Promise<CollectionEntry<C>[]>;
|
||||
|
||||
export function getEntry<
|
||||
C extends keyof ContentEntryMap,
|
||||
E extends ValidContentEntrySlug<C> | (string & {}),
|
||||
>(entry: {
|
||||
collection: C;
|
||||
slug: 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]
|
||||
? Promise<DataEntryMap[C][E]>
|
||||
: Promise<CollectionEntry<C> | undefined>;
|
||||
export function getEntry<
|
||||
C extends keyof ContentEntryMap,
|
||||
E extends ValidContentEntrySlug<C> | (string & {}),
|
||||
>(
|
||||
collection: C,
|
||||
slug: 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 & {}),
|
||||
>(
|
||||
collection: C,
|
||||
id: E,
|
||||
): E extends keyof DataEntryMap[C]
|
||||
? Promise<DataEntryMap[C][E]>
|
||||
: Promise<CollectionEntry<C> | undefined>;
|
||||
|
||||
/** Resolve an array of entry references from the same collection */
|
||||
export function getEntries<C extends keyof ContentEntryMap>(
|
||||
entries: {
|
||||
collection: C;
|
||||
slug: ValidContentEntrySlug<C>;
|
||||
}[],
|
||||
): Promise<CollectionEntry<C>[]>;
|
||||
export function getEntries<C extends keyof DataEntryMap>(
|
||||
entries: {
|
||||
collection: C;
|
||||
id: keyof DataEntryMap[C];
|
||||
}[],
|
||||
): Promise<CollectionEntry<C>[]>;
|
||||
|
||||
export function render<C extends keyof AnyEntryMap>(
|
||||
entry: AnyEntryMap[C][string],
|
||||
): Promise<RenderResult>;
|
||||
|
||||
export function reference<C extends keyof AnyEntryMap>(
|
||||
collection: C,
|
||||
): import('astro/zod').ZodEffects<
|
||||
import('astro/zod').ZodString,
|
||||
C extends keyof ContentEntryMap
|
||||
? {
|
||||
collection: C;
|
||||
slug: ValidContentEntrySlug<C>;
|
||||
}
|
||||
: {
|
||||
collection: C;
|
||||
id: keyof DataEntryMap[C];
|
||||
}
|
||||
>;
|
||||
// Allow generic `string` to avoid excessive type errors in the config
|
||||
// if `dev` is not running to update as you edit.
|
||||
// Invalid collection names will be caught at build time.
|
||||
export function reference<C extends string>(
|
||||
collection: C,
|
||||
): import('astro/zod').ZodEffects<import('astro/zod').ZodString, never>;
|
||||
|
||||
type ReturnTypeOrOriginal<T> = T extends (...args: any[]) => infer R ? R : T;
|
||||
type InferEntrySchema<C extends keyof AnyEntryMap> = import('astro/zod').infer<
|
||||
ReturnTypeOrOriginal<Required<ContentConfig['collections'][C]>['schema']>
|
||||
>;
|
||||
|
||||
type ContentEntryMap = {
|
||||
// @@CONTENT_ENTRY_MAP@@
|
||||
};
|
||||
|
||||
type DataEntryMap = {
|
||||
// @@DATA_ENTRY_MAP@@
|
||||
};
|
||||
|
||||
type AnyEntryMap = ContentEntryMap & DataEntryMap;
|
||||
|
||||
export type ContentConfig = '@@CONTENT_CONFIG_TYPE@@';
|
||||
}
|
33
node_modules/astro/templates/env/module.mjs
generated
vendored
Normal file
33
node_modules/astro/templates/env/module.mjs
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// @ts-check
|
||||
import { schema } from 'virtual:astro:env/internal';
|
||||
import {
|
||||
createInvalidVariablesError,
|
||||
getEnv,
|
||||
getEnvFieldType,
|
||||
setOnSetGetEnv,
|
||||
validateEnvVariable,
|
||||
} from 'astro/env/runtime';
|
||||
|
||||
export const getSecret = (key) => {
|
||||
return getEnv(key);
|
||||
};
|
||||
|
||||
const _internalGetSecret = (key) => {
|
||||
const rawVariable = getEnv(key);
|
||||
const variable = rawVariable === '' ? undefined : rawVariable;
|
||||
const options = schema[key];
|
||||
|
||||
const result = validateEnvVariable(variable, options);
|
||||
if (result.ok) {
|
||||
return result.value;
|
||||
}
|
||||
const type = getEnvFieldType(options);
|
||||
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) => {
|
||||
// @@ON_SET_GET_ENV@@
|
||||
});
|
9
node_modules/astro/templates/env/types.d.ts
generated
vendored
Normal file
9
node_modules/astro/templates/env/types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
declare module 'astro:env/client' {
|
||||
// @@CLIENT@@
|
||||
}
|
||||
|
||||
declare module 'astro:env/server' {
|
||||
// @@SERVER@@
|
||||
|
||||
export const getSecret: (key: string) => string | undefined;
|
||||
}
|
Reference in New Issue
Block a user