From 81cb08a0d20bd2aa3e3874b49c85cf46f228ece5 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Fri, 19 Sep 2025 11:06:02 +0100 Subject: [PATCH 01/19] wip --- packages/astro/src/config/index.ts | 13 +- .../src/config/vite-plugin-content-listen.ts | 41 -- packages/astro/src/content/loaders/glob.ts | 34 +- packages/astro/src/content/runtime.ts | 94 +--- .../astro/src/content/server-listeners.ts | 78 +-- packages/astro/src/content/types-generator.ts | 117 +---- packages/astro/src/content/utils.ts | 198 +------- .../vite-plugin-content-virtual-mod.ts | 167 +------ .../astro/src/core/config/schemas/base.ts | 6 +- packages/astro/src/core/sync/index.ts | 13 +- packages/astro/src/types/public/config.ts | 43 +- packages/astro/templates/content/module.mjs | 59 +-- packages/astro/templates/content/types.d.ts | 11 - packages/astro/test/astro-sync.test.js | 6 - .../test/content-collections-render.test.js | 19 - packages/astro/test/core-image.test.js | 5 - .../test/fixtures/content/astro.config.mjs | 4 - .../src/content/blog/with-layout-prop.md | 9 - .../core-image-errors/astro.config.mjs | 4 - .../test/fixtures/core-image/astro.config.mjs | 4 - .../core-image/src/content/blog/one.md | 1 - .../fixtures/core-image/src/content/config.ts | 1 - .../core-image/src/pages/blog/[...slug].astro | 4 - .../css-inline-stylesheets-2/astro.config.mjs | 5 +- .../src/content/en/endeavour.md | 1 - .../css-inline-stylesheets-3/astro.config.mjs | 5 +- .../src/content/en/endeavour.md | 3 +- .../css-inline-stylesheets/astro.config.mjs | 4 - .../src/content/en/endeavour.md | 1 - .../test/legacy-content-collections.test.js | 456 ------------------ .../test/legacy-data-collections.test.js | 159 ------ .../collections-mixed-content-errors.test.js | 147 ------ .../units/dev/collections-renderentry.test.js | 298 ------------ 33 files changed, 51 insertions(+), 1959 deletions(-) delete mode 100644 packages/astro/src/config/vite-plugin-content-listen.ts delete mode 100644 packages/astro/test/fixtures/content/src/content/blog/with-layout-prop.md delete mode 100644 packages/astro/test/legacy-content-collections.test.js delete mode 100644 packages/astro/test/legacy-data-collections.test.js delete mode 100644 packages/astro/test/units/dev/collections-mixed-content-errors.test.js delete mode 100644 packages/astro/test/units/dev/collections-renderentry.test.js diff --git a/packages/astro/src/config/index.ts b/packages/astro/src/config/index.ts index 53c513f3973e..13751611f479 100644 --- a/packages/astro/src/config/index.ts +++ b/packages/astro/src/config/index.ts @@ -35,21 +35,17 @@ export function getViteConfig( // Use dynamic import to avoid pulling in deps unless used const [ - fs, { mergeConfig }, { createNodeLogger }, { resolveConfig, createSettings }, { createVite }, { runHookConfigSetup, runHookConfigDone }, - { astroContentListenPlugin }, ] = await Promise.all([ - import('node:fs'), import('vite'), import('../core/config/logging.js'), import('../core/config/index.js'), import('../core/create-vite.js'), import('../integrations/hooks.js'), - import('./vite-plugin-content-listen.js'), ]); const logger = createNodeLogger(inlineAstroConfig); const { astroConfig: config } = await resolveConfig(inlineAstroConfig, cmd); @@ -58,14 +54,7 @@ export function getViteConfig( const routesList = await createRoutesList({ settings }, logger); const manifest = createDevelopmentManifest(settings); const viteConfig = await createVite( - { - plugins: config.legacy.collections - ? [ - // Initialize the content listener - astroContentListenPlugin({ settings, logger, fs }), - ] - : [], - }, + {}, { settings, command: cmd, logger, mode, sync: false, manifest, routesList }, ); await runHookConfigDone({ settings, logger }); diff --git a/packages/astro/src/config/vite-plugin-content-listen.ts b/packages/astro/src/config/vite-plugin-content-listen.ts deleted file mode 100644 index 6c0408001954..000000000000 --- a/packages/astro/src/config/vite-plugin-content-listen.ts +++ /dev/null @@ -1,41 +0,0 @@ -import type fsMod from 'node:fs'; -import type { Plugin, ViteDevServer } from 'vite'; -import { attachContentServerListeners } from '../content/server-listeners.js'; -import type { Logger } from '../core/logger/core.js'; -import type { AstroSettings } from '../types/astro.js'; - -/** - * Listen for Astro content directory changes and generate types. - * - * This is a separate plugin for `getViteConfig` as the `attachContentServerListeners` API - * needs to be called at different times in `astro dev` and `getViteConfig`. For `astro dev`, - * it needs to be called after the Astro server is started (packages/astro/src/core/dev/dev.ts). - * For `getViteConfig`, it needs to be called after the Vite server is started. - */ -export function astroContentListenPlugin({ - settings, - logger, - fs, -}: { - settings: AstroSettings; - logger: Logger; - fs: typeof fsMod; -}): Plugin { - let server: ViteDevServer; - - return { - name: 'astro:content-listen', - apply: 'serve', - configureServer(_server) { - server = _server; - }, - async buildStart() { - await attachContentServerListeners({ - fs: fs, - settings, - logger, - viteServer: server, - }); - }, - }; -} diff --git a/packages/astro/src/content/loaders/glob.ts b/packages/astro/src/content/loaders/glob.ts index ab78f2a76425..dca06479dbe8 100644 --- a/packages/astro/src/content/loaders/glob.ts +++ b/packages/astro/src/content/loaders/glob.ts @@ -56,14 +56,6 @@ function checkPrefix(pattern: string | Array, prefix: string) { * Loads multiple entries, using a glob pattern to match files. * @param pattern A glob pattern to match files, relative to the content directory. */ -export function glob(globOptions: GlobOptions): Loader; -/** @private */ -export function glob( - globOptions: GlobOptions & { - /** @deprecated */ - _legacy?: true; - }, -): Loader; export function glob(globOptions: GlobOptions): Loader { if (checkPrefix(globOptions.pattern, '../')) { @@ -90,9 +82,6 @@ export function glob(globOptions: GlobOptions): Loader { >(); const untouchedEntries = new Set(store.keys()); - const isLegacy = (globOptions as any)._legacy; - // If global legacy collection handling flag is *not* enabled then this loader is used to emulate them instead - const emulateLegacyCollections = !config.legacy.collections; async function syncData( entry: string, base: URL, @@ -125,17 +114,6 @@ export function glob(globOptions: GlobOptions): Loader { store.delete(oldId); } - let legacyId: string | undefined; - - if (isLegacy) { - const entryURL = new URL(encodeURI(entry), base); - const legacyOptions = getContentEntryIdAndSlug({ - entry: entryURL, - contentDir: base, - collection: '', - }); - legacyId = legacyOptions.id; - } untouchedEntries.delete(id); const existingEntry = store.get(id); @@ -165,12 +143,6 @@ export function glob(globOptions: GlobOptions): Loader { filePath, }); if (entryType.getRenderFunction) { - if (isLegacy && data.layout) { - logger.error( - `The Markdown "layout" field is not supported in content collections in Astro 5. Ignoring layout for ${JSON.stringify(entry)}. Enable "legacy.collections" if you need to use the layout field.`, - ); - } - let render = renderFunctionByContentType.get(entryType); if (!render) { render = await entryType.getRenderFunction(config); @@ -199,7 +171,6 @@ export function glob(globOptions: GlobOptions): Loader { digest, rendered, assetImports: rendered?.metadata?.imagePaths, - legacyId, }); // todo: add an explicit way to opt in to deferred rendering @@ -211,10 +182,9 @@ export function glob(globOptions: GlobOptions): Loader { filePath: relativePath, digest, deferredRender: true, - legacyId, }); } else { - store.set({ id, data: parsedData, body, filePath: relativePath, digest, legacyId }); + store.set({ id, data: parsedData, body, filePath: relativePath, digest }); } fileToIdMap.set(filePath, id); @@ -281,7 +251,7 @@ export function glob(globOptions: GlobOptions): Loader { if (isConfigFile(entry)) { return; } - if (!emulateLegacyCollections && isInContentDir(entry)) { + if (isInContentDir(entry)) { skippedFiles.push(entry); return; } diff --git a/packages/astro/src/content/runtime.ts b/packages/astro/src/content/runtime.ts index 484642fe81a4..87e29f21ed42 100644 --- a/packages/astro/src/content/runtime.ts +++ b/packages/astro/src/content/runtime.ts @@ -1,7 +1,6 @@ import type { MarkdownHeading } from '@astrojs/markdown-remark'; import { escape } from 'html-escaper'; import { Traverse } from 'neotraverse/modern'; -import pLimit from 'p-limit'; import { ZodIssueCode, z } from 'zod'; import type { GetImageResult, ImageMetadata } from '../assets/types.js'; import { imageSrcToImportId } from '../assets/utils/resolveImports.js'; @@ -34,7 +33,6 @@ import { LiveEntryNotFoundError, } from './loaders/errors.js'; import type { LiveLoader } from './loaders/types.js'; -import type { ContentLookupMap } from './utils.js'; export { LiveCollectionError, LiveCollectionCacheHintError, @@ -115,16 +113,8 @@ async function parseLiveEntry( } export function createGetCollection({ - contentCollectionToEntryMap, - dataCollectionToEntryMap, - getRenderEntryImport, - cacheEntriesByCollection, liveCollections, }: { - contentCollectionToEntryMap: CollectionToEntryMap; - dataCollectionToEntryMap: CollectionToEntryMap; - getRenderEntryImport: GetEntryImport; - cacheEntriesByCollection: Map; liveCollections: LiveCollectionConfigMap; }) { return async function getCollection( @@ -140,12 +130,7 @@ export function createGetCollection({ const hasFilter = typeof filter === 'function'; const store = await globalDataStore.get(); - let type: 'content' | 'data'; - if (collection in contentCollectionToEntryMap) { - type = 'content'; - } else if (collection in dataCollectionToEntryMap) { - type = 'data'; - } else if (store.hasCollection(collection)) { + if (store.hasCollection(collection)) { // @ts-expect-error virtual module const { default: imageAssetMap } = await import('astro:asset-imports'); @@ -177,55 +162,6 @@ export function createGetCollection({ ); return []; } - - const lazyImports = Object.values( - type === 'content' - ? contentCollectionToEntryMap[collection] - : dataCollectionToEntryMap[collection], - ); - let entries: any[] = []; - // Cache `getCollection()` calls in production only - // prevents stale cache in development - if (!import.meta.env?.DEV && cacheEntriesByCollection.has(collection)) { - entries = cacheEntriesByCollection.get(collection)!; - } else { - const limit = pLimit(10); - entries = await Promise.all( - lazyImports.map((lazyImport) => - limit(async () => { - const entry = await lazyImport(); - return type === 'content' - ? { - id: entry.id, - slug: entry.slug, - body: entry.body, - collection: entry.collection, - data: entry.data, - async render() { - return render({ - collection: entry.collection, - id: entry.id, - renderEntryImport: await getRenderEntryImport(collection, entry.slug), - }); - }, - } - : { - id: entry.id, - collection: entry.collection, - data: entry.data, - }; - }), - ), - ); - cacheEntriesByCollection.set(collection, entries); - } - if (hasFilter) { - return entries.filter(filter); - } else { - // Clone the array so users can safely mutate it. - // slice() is faster than ...spread for large arrays. - return entries.slice(); - } }; } @@ -882,7 +818,7 @@ async function render({ } } -export function createReference({ lookupMap }: { lookupMap: ContentLookupMap }) { +export function createReference() { return function reference(collection: string) { return z .union([ @@ -915,36 +851,10 @@ export function createReference({ lookupMap }: { lookupMap: ContentLookupMap }) }); return; } - // We won't throw if the collection is missing, because it may be a content layer collection and the store may not yet be populated. // If it is an object then we're validating later in the build, so we can check the collection at that point. - return lookup; } - // If the collection is not in the lookup map it may be a content layer collection and the store may not yet be populated. - if (!lookupMap[collection]) { - // For now, we can't validate this reference, so we'll optimistically convert it to a reference object which we'll validate - // later in the pipeline when we do have access to the store. - return { id: lookup, collection }; - } - const { type, entries } = lookupMap[collection]; - const entry = entries[lookup]; - - if (!entry) { - ctx.addIssue({ - code: ZodIssueCode.custom, - message: `**${flattenedErrorPath}**: Reference to ${collection} invalid. Expected ${Object.keys( - entries, - ) - .map((c) => JSON.stringify(c)) - .join(' | ')}. Received ${JSON.stringify(lookup)}.`, - }); - return; - } - // Content is still identified by slugs, so map to a `slug` key for consistency. - if (type === 'content') { - return { slug: lookup, collection }; - } return { id: lookup, collection }; }, ); diff --git a/packages/astro/src/content/server-listeners.ts b/packages/astro/src/content/server-listeners.ts index 492a5a5160cf..c42b39519f73 100644 --- a/packages/astro/src/content/server-listeners.ts +++ b/packages/astro/src/content/server-listeners.ts @@ -1,14 +1,9 @@ import type fsMod from 'node:fs'; -import path from 'node:path'; -import { fileURLToPath, pathToFileURL } from 'node:url'; -import { bold, cyan, underline } from 'kleur/colors'; import type { ViteDevServer } from 'vite'; -import { loadTSConfig } from '../core/config/tsconfig.js'; import type { Logger } from '../core/logger/core.js'; -import { appendForwardSlash } from '../core/path.js'; import type { AstroSettings } from '../types/astro.js'; import { createContentTypesGenerator } from './types-generator.js'; -import { type ContentPaths, getContentPaths, globalContentConfigObserver } from './utils.js'; +import { globalContentConfigObserver } from './utils.js'; interface ContentServerListenerParams { fs: typeof fsMod; @@ -23,31 +18,6 @@ export async function attachContentServerListeners({ logger, settings, }: ContentServerListenerParams) { - const contentPaths = getContentPaths(settings.config, fs); - if (!settings.config.legacy?.collections) { - await attachListeners(); - } else if (fs.existsSync(contentPaths.contentDir)) { - logger.debug( - 'content', - `Watching ${cyan( - contentPaths.contentDir.href.replace(settings.config.root.href, ''), - )} for changes`, - ); - const maybeTsConfigStats = await getTSConfigStatsWhenAllowJsFalse({ contentPaths, settings }); - if (maybeTsConfigStats) warnAllowJsIsFalse({ ...maybeTsConfigStats, logger }); - await attachListeners(); - } else { - viteServer.watcher.on('addDir', contentDirListener); - async function contentDirListener(dir: string) { - if (appendForwardSlash(pathToFileURL(dir).href) === contentPaths.contentDir.href) { - logger.debug('content', `Content directory found. Watching for changes`); - await attachListeners(); - viteServer.watcher.removeListener('addDir', contentDirListener); - } - } - } - - async function attachListeners() { const contentGenerator = await createContentTypesGenerator({ fs, settings, @@ -73,51 +43,5 @@ export async function attachContentServerListeners({ viteServer.watcher.on('unlinkDir', (entry) => contentGenerator.queueEvent({ name: 'unlinkDir', entry }), ); - } -} - -function warnAllowJsIsFalse({ - logger, - tsConfigFileName, - contentConfigFileName, -}: { - logger: Logger; - tsConfigFileName: string; - contentConfigFileName: string; -}) { - logger.warn( - 'content', - `Make sure you have the ${bold('allowJs')} compiler option set to ${bold( - 'true', - )} in your ${bold(tsConfigFileName)} file to have autocompletion in your ${bold( - contentConfigFileName, - )} file. See ${underline( - cyan('https://www.typescriptlang.org/tsconfig#allowJs'), - )} for more information.`, - ); -} - -async function getTSConfigStatsWhenAllowJsFalse({ - contentPaths, - settings, -}: { - contentPaths: ContentPaths; - settings: AstroSettings; -}) { - const isContentConfigJsFile = ['.js', '.mjs'].some((ext) => - contentPaths.config.url.pathname.endsWith(ext), - ); - if (!isContentConfigJsFile) return; - - const inputConfig = await loadTSConfig(fileURLToPath(settings.config.root)); - if (typeof inputConfig === 'string') return; - - const tsConfigFileName = inputConfig.tsconfigFile.split(path.sep).pop(); - if (!tsConfigFileName) return; - - const contentConfigFileName = contentPaths.config.url.pathname.split(path.sep).pop()!; - const allowJSOption = inputConfig.tsconfig.compilerOptions?.allowJs; - if (allowJSOption) return; - return { tsConfigFileName, contentConfigFileName }; } diff --git a/packages/astro/src/content/types-generator.ts b/packages/astro/src/content/types-generator.ts index ac6d1c51e64d..27a99075984e 100644 --- a/packages/astro/src/content/types-generator.ts +++ b/packages/astro/src/content/types-generator.ts @@ -2,12 +2,11 @@ import type fsMod from 'node:fs'; import * as path from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; import { bold, cyan } from 'kleur/colors'; -import { glob } from 'tinyglobby'; import { normalizePath, type ViteDevServer } from 'vite'; import { type ZodSchema, z } from 'zod'; import { zodToJsonSchema } from 'zod-to-json-schema'; import { AstroError } from '../core/errors/errors.js'; -import { AstroErrorData, AstroUserError } from '../core/errors/index.js'; +import { AstroErrorData } from '../core/errors/index.js'; import type { Logger } from '../core/logger/core.js'; import { isRelativePath } from '../core/path.js'; import type { AstroSettings } from '../types/astro.js'; @@ -88,33 +87,9 @@ export async function createContentTypesGenerator({ const typeTemplateContent = await fs.promises.readFile(contentPaths.typesTemplate, 'utf-8'); - async function init(): Promise< - { typesGenerated: true } | { typesGenerated: false; reason: 'no-content-dir' } - > { + async function init(): Promise { events.push({ name: 'add', entry: contentPaths.config.url }); - - if (settings.config.legacy.collections) { - if (!fs.existsSync(contentPaths.contentDir)) { - return { typesGenerated: false, reason: 'no-content-dir' }; - } - const globResult = await glob('**', { - cwd: fileURLToPath(contentPaths.contentDir), - absolute: true, - }); - - for (const fullPath of globResult) { - const entryURL = pathToFileURL(fullPath); - if (entryURL.href.startsWith(contentPaths.config.url.href)) continue; - const stat = fs.statSync(fullPath); - if (stat.isFile()) { - events.push({ name: 'add', entry: entryURL }); - } else if (stat.isDirectory()) { - events.push({ name: 'addDir', entry: entryURL }); - } - } - } await runEvents(); - return { typesGenerated: true }; } async function handleEvent(event: ContentEvent): Promise<{ shouldGenerateTypes: boolean }> { @@ -293,11 +268,7 @@ export async function createContentTypesGenerator({ name: rawEvent.name, }; - if (settings.config.legacy.collections) { - if (!event.entry.pathname.startsWith(contentPaths.contentDir.pathname)) { - return; - } - } else if (contentPaths.config.url.pathname !== event.entry.pathname) { + if (contentPaths.config.url.pathname !== event.entry.pathname) { return; } @@ -405,24 +376,24 @@ async function typeForCollection( if (collection?.schema) { return `InferEntrySchema<${collectionKey}>`; } - - if (collection?.type === CONTENT_LAYER_TYPE) { - const schema = await getContentLayerSchema(collection, collectionKey); - if (schema) { - try { - const zodToTs = await import('zod-to-ts'); - const ast = zodToTs.zodToTs(schema); - return zodToTs.printNode(ast.node); - } catch (err: any) { - // zod-to-ts is sad if we don't have TypeScript installed, but that's fine as we won't be needing types in that case - if (err.message.includes("Cannot find package 'typescript'")) { - return 'any'; - } - throw err; - } + if (!collection?.type) { + return 'any'; + } + const schema = await getContentLayerSchema(collection, collectionKey); + if (!schema) { + return 'any'; + } + try { + const zodToTs = await import('zod-to-ts'); + const ast = zodToTs.zodToTs(schema); + return zodToTs.printNode(ast.node); + } catch (err: any) { + // zod-to-ts is sad if we don't have TypeScript installed, but that's fine as we won't be needing types in that case + if (err.message.includes("Cannot find package 'typescript'")) { + return 'any'; } + throw err; } - return 'any'; } async function writeContentFiles({ @@ -489,56 +460,10 @@ async function writeContentFiles({ }); return; } - const resolvedType = - collection.type === 'unknown' - ? // Add empty / unknown collections to the data type map by default - // This ensures `getCollection('empty-collection')` doesn't raise a type error - (collectionConfig?.type ?? 'data') - : collection.type; - const collectionEntryKeys = Object.keys(collection.entries).sort(); + const dataType = await typeForCollection(collectionConfig, collectionKey); - switch (resolvedType) { - case LIVE_CONTENT_TYPE: - // This error should never be thrown, as it should have been caught earlier in the process - throw new AstroUserError( - `Invalid definition for collection ${collectionKey}: Live content collections must be defined in "src/live.config.ts"`, - ); - case 'content': - if (collectionEntryKeys.length === 0) { - contentTypesStr += `${collectionKey}: Record;\n`; - break; - } - contentTypesStr += `${collectionKey}: {\n`; - for (const entryKey of collectionEntryKeys) { - const entryMetadata = collection.entries[entryKey]; - const renderType = `{ render(): Render[${JSON.stringify( - path.extname(JSON.parse(entryKey)), - )}] }`; - - const slugType = JSON.stringify(entryMetadata.slug); - contentTypesStr += `${entryKey}: {\n id: ${entryKey};\n slug: ${slugType};\n body: string;\n collection: ${collectionKey};\n data: ${dataType}\n} & ${renderType};\n`; - } - contentTypesStr += `};\n`; - break; - case CONTENT_LAYER_TYPE: - const legacyTypes = (collectionConfig as any)?._legacy - ? 'render(): Render[".md"];\n slug: string;\n body: string;\n' - : 'body?: string;\n'; - dataTypesStr += `${collectionKey}: Record;\n`; - break; - case 'data': - if (collectionEntryKeys.length === 0) { - dataTypesStr += `${collectionKey}: Record;\n`; - } else { - dataTypesStr += `${collectionKey}: {\n`; - for (const entryKey of collectionEntryKeys) { - dataTypesStr += `${entryKey}: {\n id: ${entryKey};\n collection: ${collectionKey};\n data: ${dataType}\n};\n`; - } - dataTypesStr += `};\n`; - } - break; - } + dataTypesStr += `${collectionKey}: Record;\n`; if ( collectionConfig && diff --git a/packages/astro/src/content/utils.ts b/packages/astro/src/content/utils.ts index 851907d4c3f4..8e2c04c737f2 100644 --- a/packages/astro/src/content/utils.ts +++ b/packages/astro/src/content/utils.ts @@ -11,7 +11,6 @@ import { z } from 'zod'; import { AstroError, AstroErrorData, errorMap, MarkdownError } from '../core/errors/index.js'; import { isYAMLException } from '../core/errors/utils.js'; import type { Logger } from '../core/logger/core.js'; -import { appendForwardSlash } from '../core/path.js'; import { normalizePath } from '../core/viteUtils.js'; import type { AstroSettings } from '../types/astro.js'; import type { AstroConfig } from '../types/public/config.js'; @@ -25,18 +24,8 @@ import { LIVE_CONTENT_TYPE, PROPAGATED_ASSET_FLAG, } from './consts.js'; -import { glob } from './loaders/glob.js'; import { createImage } from './runtime-assets.js'; -/** - * A map from a collection + slug to the local file path. - * This is used internally to resolve entry imports when using `getEntry()`. - * @see `templates/content/module.mjs` - */ -export type ContentLookupMap = { - [collectionName: string]: { type: 'content' | 'data'; entries: { [lookupId: string]: string } }; -}; - const entryTypeSchema = z .object({ id: z.string({ @@ -63,14 +52,6 @@ export const loaderReturnSchema = z.union([ ]); const collectionConfigParser = z.union([ - z.object({ - type: z.literal('content').optional().default('content'), - schema: z.any().optional(), - }), - z.object({ - type: z.literal('data'), - schema: z.any().optional(), - }), z.object({ type: z.literal(CONTENT_LAYER_TYPE), schema: z.any().optional(), @@ -102,8 +83,6 @@ const collectionConfigParser = z.union([ render: z.function(z.tuple([z.any()], z.unknown())).optional(), }), ]), - /** deprecated */ - _legacy: z.boolean().optional(), }), z.object({ type: z.literal(LIVE_CONTENT_TYPE).optional().default(LIVE_CONTENT_TYPE), @@ -157,14 +136,7 @@ export async function getEntryDataAndImages< experimentalSvgEnabled: boolean, pluginContext?: PluginContext, ): Promise<{ data: TOutputData; imageImports: Array }> { - let data: TOutputData; - // Legacy content collections have 'slug' removed - if (collectionConfig.type === 'content' || (collectionConfig as any)._legacy) { - const { slug, ...unvalidatedData } = entry.unvalidatedData; - data = unvalidatedData as TOutputData; - } else { - data = entry.unvalidatedData as TOutputData; - } + let data = entry.unvalidatedData as TOutputData; let schema = collectionConfig.schema; @@ -192,20 +164,6 @@ export async function getEntryDataAndImages< } if (schema) { - // Catch reserved `slug` field inside content schemas - // Note: will not warn for `z.union` or `z.intersection` schemas - if ( - collectionConfig.type === 'content' && - typeof schema === 'object' && - 'shape' in schema && - schema.shape.slug - ) { - throw new AstroError({ - ...AstroErrorData.ContentSchemaContainsSlugError, - message: AstroErrorData.ContentSchemaContainsSlugError.message(entry.collection), - }); - } - // Use `safeParseAsync` to allow async transforms let formattedError; const parsed = await (schema as z.ZodSchema).safeParseAsync(data, { @@ -220,13 +178,13 @@ export async function getEntryDataAndImages< data = parsed.data as TOutputData; } else { if (!formattedError) { - const errorType = - collectionConfig.type === 'content' - ? AstroErrorData.InvalidContentEntryFrontmatterError - : AstroErrorData.InvalidContentEntryDataError; formattedError = new AstroError({ - ...errorType, - message: errorType.message(entry.collection, entry.id, parsed.error), + ...AstroErrorData.InvalidContentEntryDataError, + message: AstroErrorData.InvalidContentEntryDataError.message( + entry.collection, + entry.id, + parsed.error, + ), location: { file: entry._internal?.filePath, line: getYAMLErrorLine( @@ -560,100 +518,6 @@ async function loadContentConfig({ } } -async function autogenerateCollections({ - config, - settings, - fs, -}: { - config?: ContentConfig; - settings: AstroSettings; - fs: typeof fsMod; -}): Promise { - if (settings.config.legacy.collections) { - return config; - } - const contentDir = new URL('./content/', settings.config.srcDir); - - const collections: Record = config?.collections ?? {}; - - const contentExts = getContentEntryExts(settings); - const dataExts = getDataEntryExts(settings); - - const contentPattern = globWithUnderscoresIgnored('', contentExts); - const dataPattern = globWithUnderscoresIgnored('', dataExts); - let usesContentLayer = false; - for (const collectionName of Object.keys(collections)) { - if ( - collections[collectionName]?.type === 'content_layer' || - collections[collectionName]?.type === 'live' - ) { - usesContentLayer = true; - // This is already a content layer, skip - continue; - } - - const isDataCollection = collections[collectionName]?.type === 'data'; - const base = new URL(`${collectionName}/`, contentDir); - // Only "content" collections need special legacy handling - const _legacy = !isDataCollection || undefined; - collections[collectionName] = { - ...collections[collectionName], - type: 'content_layer', - _legacy, - loader: glob({ - base, - pattern: isDataCollection ? dataPattern : contentPattern, - _legacy, - // Legacy data collections IDs aren't slugified - generateId: isDataCollection - ? ({ entry }) => - getDataEntryId({ - entry: new URL(entry, base), - collection: collectionName, - contentDir, - }) - : undefined, - - // Zod weirdness has trouble with typing the args to the load function - }) as any, - }; - } - if (!usesContentLayer && fs.existsSync(contentDir)) { - // If the user hasn't defined any collections using the content layer, we'll try and help out by checking for - // any orphaned folders in the content directory and creating collections for them. - const orphanedCollections = []; - for (const entry of await fs.promises.readdir(contentDir, { withFileTypes: true })) { - const collectionName = entry.name; - if (['_', '.'].includes(collectionName.at(0) ?? '')) { - continue; - } - if (entry.isDirectory() && !(collectionName in collections)) { - orphanedCollections.push(collectionName); - const base = new URL(`${collectionName}/`, contentDir); - collections[collectionName] = { - type: 'content_layer', - loader: glob({ - base, - pattern: contentPattern, - _legacy: true, - }) as any, - }; - } - } - if (orphanedCollections.length > 0) { - console.warn( - ` -Auto-generating collections for folders in "src/content/" that are not defined as collections. -This is deprecated, so you should define these collections yourself in "src/content.config.ts". -The following collections have been auto-generated: ${orphanedCollections - .map((name) => green(name)) - .join(', ')}\n`, - ); - } - } - return { ...config, collections }; -} - export async function reloadContentConfigObserver({ observer = globalContentConfigObserver, ...loadContentConfigOpts @@ -667,11 +531,6 @@ export async function reloadContentConfigObserver({ try { let config = await loadContentConfig(loadContentConfigOpts); - config = await autogenerateCollections({ - config, - ...loadContentConfigOpts, - }); - if (config) { observer.set({ status: 'loaded', config }); } else { @@ -741,15 +600,10 @@ export type ContentPaths = { }; export function getContentPaths( - { - srcDir, - legacy, - root, - experimental, - }: Pick, + { srcDir, root, experimental }: Pick, fs: typeof fsMod = fsMod, ): ContentPaths { - const configStats = searchConfig(fs, srcDir, legacy?.collections); + const configStats = searchConfig(fs, srcDir); const liveConfigStats = experimental?.liveContentCollections ? searchLiveConfig(fs, srcDir) : { exists: false, url: new URL('./', srcDir) }; @@ -765,19 +619,12 @@ export function getContentPaths( }; } -function searchConfig( - fs: typeof fsMod, - srcDir: URL, - legacy?: boolean, -): { exists: boolean; url: URL } { +function searchConfig(fs: typeof fsMod, srcDir: URL): { exists: boolean; url: URL } { const paths = [ - ...(legacy - ? [] - : ['content.config.mjs', 'content.config.js', 'content.config.mts', 'content.config.ts']), - 'content/config.mjs', - 'content/config.js', - 'content/config.mts', - 'content/config.ts', + 'content.config.mjs', + 'content.config.js', + 'content.config.mts', + 'content.config.ts', ]; return search(fs, srcDir, paths); } @@ -830,13 +677,6 @@ export async function getEntrySlug({ return parseEntrySlug({ generatedSlug, frontmatterSlug, id, collection }); } -export function getExtGlob(exts: string[]) { - return exts.length === 1 - ? // Wrapping {...} breaks when there is only one extension - exts[0] - : `{${exts.join(',')}}`; -} - export function hasAssetPropagationFlag(id: string): boolean { try { return new URL(id, 'file://').searchParams.has(PROPAGATED_ASSET_FLAG); @@ -845,16 +685,6 @@ export function hasAssetPropagationFlag(id: string): boolean { } } -export function globWithUnderscoresIgnored(relContentDir: string, exts: string[]): string[] { - const extGlob = getExtGlob(exts); - const contentDir = relContentDir.length > 0 ? appendForwardSlash(relContentDir) : relContentDir; - return [ - `${contentDir}**/*${extGlob}`, - `!${contentDir}**/_*/**/*${extGlob}`, - `!${contentDir}**/_*${extGlob}`, - ]; -} - /** * Convert a platform path to a posix path. */ diff --git a/packages/astro/src/content/vite-plugin-content-virtual-mod.ts b/packages/astro/src/content/vite-plugin-content-virtual-mod.ts index e244b6697ada..05818737bf6a 100644 --- a/packages/astro/src/content/vite-plugin-content-virtual-mod.ts +++ b/packages/astro/src/content/vite-plugin-content-virtual-mod.ts @@ -1,9 +1,6 @@ import nodeFs from 'node:fs'; -import { extname } from 'node:path'; -import { fileURLToPath, pathToFileURL } from 'node:url'; +import { fileURLToPath } from 'node:url'; import { dataToEsm } from '@rollup/pluginutils'; -import pLimit from 'p-limit'; -import { glob } from 'tinyglobby'; import { normalizePath, type Plugin, type ViteDevServer } from 'vite'; import { AstroError, AstroErrorData } from '../core/errors/index.js'; import { rootRelativePath } from '../core/viteUtils.js'; @@ -14,9 +11,7 @@ import { ASSET_IMPORTS_FILE, ASSET_IMPORTS_RESOLVED_STUB_ID, ASSET_IMPORTS_VIRTUAL_ID, - CONTENT_FLAG, CONTENT_RENDER_FLAG, - DATA_FLAG, DATA_STORE_VIRTUAL_ID, MODULES_IMPORTS_FILE, MODULES_MJS_ID, @@ -27,18 +22,8 @@ import { } from './consts.js'; import { getDataStoreFile } from './content-layer.js'; import { - type ContentLookupMap, - getContentEntryIdAndSlug, getContentPaths, - getDataEntryExts, - getDataEntryId, - getEntryCollectionName, - getEntryConfigByExtMap, - getEntrySlug, - getEntryType, - getExtGlob, - globWithUnderscoresIgnored, - isDeferredModule, + isDeferredModule } from './utils.js'; interface AstroContentVirtualModPluginParams { @@ -129,17 +114,10 @@ export function astroContentVirtualModPlugin({ }, async load(id, args) { if (id === RESOLVED_VIRTUAL_MODULE_ID) { - const lookupMap = settings.config.legacy.collections - ? await generateLookupMap({ - settings, - fs, - }) - : {}; const isClient = !args?.ssr; const code = await generateContentEntryFile({ settings, fs, - lookupMap, isClient, }); @@ -213,40 +191,15 @@ export function astroContentVirtualModPlugin({ async function generateContentEntryFile({ settings, - lookupMap, isClient, }: { settings: AstroSettings; fs: typeof nodeFs; - lookupMap: ContentLookupMap; isClient: boolean; }) { const contentPaths = getContentPaths(settings.config); const relContentDir = rootRelativePath(settings.config.root, contentPaths.contentDir); - let contentEntryGlobResult = '""'; - let dataEntryGlobResult = '""'; - let renderEntryGlobResult = '""'; - if (settings.config.legacy.collections) { - const contentEntryConfigByExt = getEntryConfigByExtMap(settings.contentEntryTypes); - const contentEntryExts = [...contentEntryConfigByExt.keys()]; - const dataEntryExts = getDataEntryExts(settings); - const createGlob = (value: string[], flag: string) => - `import.meta.glob(${JSON.stringify(value)}, { query: { ${flag}: true } })`; - contentEntryGlobResult = createGlob( - globWithUnderscoresIgnored(relContentDir, contentEntryExts), - CONTENT_FLAG, - ); - dataEntryGlobResult = createGlob( - globWithUnderscoresIgnored(relContentDir, dataEntryExts), - DATA_FLAG, - ); - renderEntryGlobResult = createGlob( - globWithUnderscoresIgnored(relContentDir, contentEntryExts), - CONTENT_RENDER_FLAG, - ); - } - let virtualModContents: string; if (isClient) { throw new AstroError({ @@ -257,10 +210,6 @@ async function generateContentEntryFile({ virtualModContents = nodeFs .readFileSync(contentPaths.virtualModTemplate, 'utf-8') .replace('@@CONTENT_DIR@@', relContentDir) - .replace("'@@CONTENT_ENTRY_GLOB_PATH@@'", contentEntryGlobResult) - .replace("'@@DATA_ENTRY_GLOB_PATH@@'", dataEntryGlobResult) - .replace("'@@RENDER_ENTRY_GLOB_PATH@@'", renderEntryGlobResult) - .replace('/* @@LOOKUP_MAP_ASSIGNMENT@@ */', `lookupMap = ${JSON.stringify(lookupMap)};`) .replace( '/* @@LIVE_CONTENT_CONFIG@@ */', contentPaths.liveConfig.exists @@ -272,115 +221,3 @@ async function generateContentEntryFile({ return virtualModContents; } - -/** - * Generate a map from a collection + slug to the local file path. - * This is used internally to resolve entry imports when using `getEntry()`. - * @see `templates/content/module.mjs` - */ -async function generateLookupMap({ settings, fs }: { settings: AstroSettings; fs: typeof nodeFs }) { - const { root } = settings.config; - const contentPaths = getContentPaths(settings.config); - const relContentDir = rootRelativePath(root, contentPaths.contentDir, false); - - const contentEntryConfigByExt = getEntryConfigByExtMap(settings.contentEntryTypes); - const dataEntryExts = getDataEntryExts(settings); - - const { contentDir } = contentPaths; - - const contentEntryExts = [...contentEntryConfigByExt.keys()]; - - let lookupMap: ContentLookupMap = {}; - const contentGlob = await glob( - `${relContentDir}**/*${getExtGlob([...dataEntryExts, ...contentEntryExts])}`, - { - absolute: true, - cwd: fileURLToPath(root), - expandDirectories: false, - }, - ); - - // Run 10 at a time to prevent `await getEntrySlug` from accessing the filesystem all at once. - // Each await shouldn't take too long for the work to be noticeably slow too. - const limit = pLimit(10); - const promises: Promise[] = []; - - for (const filePath of contentGlob) { - promises.push( - limit(async () => { - const entryType = getEntryType(filePath, contentPaths, contentEntryExts, dataEntryExts); - // Globbed ignored or unsupported entry. - // Logs warning during type generation, should ignore in lookup map. - if (entryType !== 'content' && entryType !== 'data') return; - - const collection = getEntryCollectionName({ contentDir, entry: pathToFileURL(filePath) }); - if (!collection) throw UnexpectedLookupMapError; - - if (lookupMap[collection]?.type && lookupMap[collection].type !== entryType) { - throw new AstroError({ - ...AstroErrorData.MixedContentDataCollectionError, - message: AstroErrorData.MixedContentDataCollectionError.message(collection), - }); - } - - if (entryType === 'content') { - const contentEntryType = contentEntryConfigByExt.get(extname(filePath)); - if (!contentEntryType) throw UnexpectedLookupMapError; - - const { id, slug: generatedSlug } = getContentEntryIdAndSlug({ - entry: pathToFileURL(filePath), - contentDir, - collection, - }); - const slug = await getEntrySlug({ - id, - collection, - generatedSlug, - fs, - fileUrl: pathToFileURL(filePath), - contentEntryType, - }); - if (lookupMap[collection]?.entries?.[slug]) { - throw new AstroError({ - ...AstroErrorData.DuplicateContentEntrySlugError, - message: AstroErrorData.DuplicateContentEntrySlugError.message( - collection, - slug, - lookupMap[collection].entries[slug], - rootRelativePath(root, filePath), - ), - hint: - slug !== generatedSlug - ? `Check the \`slug\` frontmatter property in **${id}**.` - : undefined, - }); - } - lookupMap[collection] = { - type: 'content', - entries: { - ...lookupMap[collection]?.entries, - [slug]: rootRelativePath(root, filePath), - }, - }; - } else { - const id = getDataEntryId({ entry: pathToFileURL(filePath), contentDir, collection }); - lookupMap[collection] = { - type: 'data', - entries: { - ...lookupMap[collection]?.entries, - [id]: rootRelativePath(root, filePath), - }, - }; - } - }), - ); - } - - await Promise.all(promises); - return lookupMap; -} - -const UnexpectedLookupMapError = new AstroError({ - ...AstroErrorData.UnknownContentCollectionError, - message: `Unexpected error while parsing content entry IDs and slugs.`, -}); diff --git a/packages/astro/src/core/config/schemas/base.ts b/packages/astro/src/core/config/schemas/base.ts index 3b6d12f0d278..61d22d5c9631 100644 --- a/packages/astro/src/core/config/schemas/base.ts +++ b/packages/astro/src/core/config/schemas/base.ts @@ -515,11 +515,7 @@ export const AstroConfigSchema = z.object({ `Invalid or outdated experimental feature.\nCheck for incorrect spelling or outdated Astro version.\nSee https://docs.astro.build/en/reference/experimental-flags/ for a list of all current experiments.`, ) .default({}), - legacy: z - .object({ - collections: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.legacy.collections), - }) - .default({}), + legacy: z.object({}).default({}), }); export type AstroConfigType = z.infer; diff --git a/packages/astro/src/core/sync/index.ts b/packages/astro/src/core/sync/index.ts index deab6e6e3db6..bc0eef18c2c0 100644 --- a/packages/astro/src/core/sync/index.ts +++ b/packages/astro/src/core/sync/index.ts @@ -171,9 +171,7 @@ export async function syncInternal({ const paths = getContentPaths(settings.config, fs); if ( paths.config.exists || - paths.liveConfig.exists || - // Legacy collections don't require a config file - (settings.config.legacy?.collections && fs.existsSync(paths.contentDir)) + paths.liveConfig.exists ) { // We only create the reference, without a stub to avoid overriding the // already generated types @@ -273,20 +271,13 @@ async function syncContentCollections( settings, viteServer: tempViteServer, }); - const typesResult = await contentTypesGenerator.init(); + await contentTypesGenerator.init(); const contentConfig = globalContentConfigObserver.get(); if (contentConfig.status === 'error') { throw contentConfig.error; } - if (typesResult.typesGenerated === false) { - switch (typesResult.reason) { - case 'no-content-dir': - default: - logger.debug('types', 'No content directory found. Skipping type generation.'); - } - } } catch (e) { const safeError = createSafeError(e) as ErrorWithMetadata; if (isAstroError(e)) { diff --git a/packages/astro/src/types/public/config.ts b/packages/astro/src/types/public/config.ts index 63ead016bf70..dcd609eb0f1e 100644 --- a/packages/astro/src/types/public/config.ts +++ b/packages/astro/src/types/public/config.ts @@ -1995,48 +1995,7 @@ export interface ViteUserConfig extends OriginalViteUserConfig { * These flags allow you to opt in to some deprecated or otherwise outdated behavior of Astro * in the latest version, so that you can continue to upgrade and take advantage of new Astro releases. */ - legacy?: { - /** - * - * @name legacy.collections - * @type {boolean} - * @default `false` - * @version 5.0.0 - * @description - * Enable legacy behavior for content collections. - * - * ```js - * // astro.config.mjs - * import { defineConfig } from 'astro/config'; - * export default defineConfig({ - * legacy: { - * collections: true - * } - * }); - * ``` - * - * If enabled, `data` and `content` collections (only) are handled using the legacy content collections implementation. Collections with a `loader` (only) will continue to use the Content Layer API instead. Both kinds of collections may exist in the same project, each using their respective implementations. - * - * The following limitations continue to exist: - * - * - Any legacy (`type: 'content'` or `type: 'data'`) collections must continue to be located in the `src/content/` directory. - * - These legacy collections will not be transformed to implicitly use the `glob()` loader, and will instead be handled by legacy code. - * - Collections using the Content Layer API (with a `loader` defined) are forbidden in `src/content/`, but may exist anywhere else in your project. - * - * When you are ready to remove this flag and migrate to the new Content Layer API for your legacy collections, you must define a collection for any directories in `src/content/` that you want to continue to use as a collection. It is sufficient to declare an empty collection, and Astro will implicitly generate an appropriate definition for your legacy collections: - * - * ```js - * // src/content.config.ts - * import { defineCollection, z } from 'astro:content'; - * - * const blog = defineCollection({ }) - * - * export const collections = { blog }; - * ``` - * - */ - collections?: boolean; - }; + legacy?: {}; /** * diff --git a/packages/astro/templates/content/module.mjs b/packages/astro/templates/content/module.mjs index 327c4a144376..bfd8e95c90fc 100644 --- a/packages/astro/templates/content/module.mjs +++ b/packages/astro/templates/content/module.mjs @@ -20,76 +20,19 @@ export { z } from 'astro/zod'; /* @@LIVE_CONTENT_CONFIG@@ */ -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, 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 reference = createReference(); export const getLiveCollection = createGetLiveCollection({ liveCollections, diff --git a/packages/astro/templates/content/types.d.ts b/packages/astro/templates/content/types.d.ts index 291d49a54e16..1341d921593e 100644 --- a/packages/astro/templates/content/types.d.ts +++ b/packages/astro/templates/content/types.d.ts @@ -157,16 +157,6 @@ declare module 'astro:content' { ReturnTypeOrOriginal['schema']> >; - type ContentEntryMap = { - // @@CONTENT_ENTRY_MAP@@ - }; - - type DataEntryMap = { - // @@DATA_ENTRY_MAP@@ - }; - - type AnyEntryMap = ContentEntryMap & DataEntryMap; - type ExtractLoaderTypes = T extends import('astro/loaders').LiveLoader< infer TData, infer TEntryFilter, @@ -175,7 +165,6 @@ declare module 'astro:content' { > ? { data: TData; entryFilter: TEntryFilter; collectionFilter: TCollectionFilter; error: TError } : { data: never; entryFilter: never; collectionFilter: never; error: never }; - type ExtractDataType = ExtractLoaderTypes['data']; type ExtractEntryFilterType = ExtractLoaderTypes['entryFilter']; type ExtractCollectionFilterType = ExtractLoaderTypes['collectionFilter']; type ExtractErrorType = ExtractLoaderTypes['error']; diff --git a/packages/astro/test/astro-sync.test.js b/packages/astro/test/astro-sync.test.js index 3e5a9bcbf330..1791c2715e8c 100644 --- a/packages/astro/test/astro-sync.test.js +++ b/packages/astro/test/astro-sync.test.js @@ -173,12 +173,6 @@ describe('astro sync', () => { ); }); - it('does not write individual types for entries when emulating legacy collections', async () => { - await fixture.load('./fixtures/content-collections/'); - fixture.clean(); - await fixture.whenSyncing(); - fixture.thenFileContentShouldNotInclude('.astro/content.d.ts', 'id: "one.md"'); - }); }); describe('astro:env', () => { diff --git a/packages/astro/test/content-collections-render.test.js b/packages/astro/test/content-collections-render.test.js index 31ed04a15ae5..607d1f9eefea 100644 --- a/packages/astro/test/content-collections-render.test.js +++ b/packages/astro/test/content-collections-render.test.js @@ -37,25 +37,6 @@ describe('Content Collections - render()', () => { assert.equal($('link[rel=stylesheet]').length, 0); }); - it('De-duplicates CSS used both in layout and directly in target page', async () => { - const html = await fixture.readFile('/with-layout-prop/index.html'); - const $ = cheerio.load(html); - - const set = new Set(); - - $('link[rel=stylesheet]').each((_, linkEl) => { - const href = linkEl.attribs.href; - assert.equal(set.has(href), false); - set.add(href); - }); - - $('style').each((_, styleEl) => { - const textContent = styleEl.children[0].data; - assert.equal(set.has(textContent), false); - set.add(textContent); - }); - }); - it('Includes component scripts for rendered entry', async () => { const html = await fixture.readFile('/launch-week-component-scripts/index.html'); const $ = cheerio.load(html); diff --git a/packages/astro/test/core-image.test.js b/packages/astro/test/core-image.test.js index 66262ce8b620..ac30a90f69b4 100644 --- a/packages/astro/test/core-image.test.js +++ b/packages/astro/test/core-image.test.js @@ -615,11 +615,6 @@ describe('astro:image', () => { assert.equal($img.attr('src').startsWith('/'), true); }); - it('has proper source for refined image', () => { - let $img = $('#refined-image img'); - assert.equal($img.attr('src').startsWith('/'), true); - }); - it('has proper sources for array of images', () => { let $img = $('#array-of-images img'); const imgsSrcs = []; diff --git a/packages/astro/test/fixtures/content/astro.config.mjs b/packages/astro/test/fixtures/content/astro.config.mjs index 71f3d1c8665d..d69e57975a64 100644 --- a/packages/astro/test/fixtures/content/astro.config.mjs +++ b/packages/astro/test/fixtures/content/astro.config.mjs @@ -3,8 +3,4 @@ import { defineConfig } from 'astro/config'; export default defineConfig({ integrations: [mdx()], - legacy: { - // Enable legacy content collections as we test layout fields - collections: true - } }); diff --git a/packages/astro/test/fixtures/content/src/content/blog/with-layout-prop.md b/packages/astro/test/fixtures/content/src/content/blog/with-layout-prop.md deleted file mode 100644 index ce8a866cb9c0..000000000000 --- a/packages/astro/test/fixtures/content/src/content/blog/with-layout-prop.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: With Layout Prop -description: Use a layout prop in a content collection -layout: "../../components/LayoutProp.astro" ---- - -## Content with a layout prop - -Sure, why not? diff --git a/packages/astro/test/fixtures/core-image-errors/astro.config.mjs b/packages/astro/test/fixtures/core-image-errors/astro.config.mjs index cc0052535c1e..027b2e69cb46 100644 --- a/packages/astro/test/fixtures/core-image-errors/astro.config.mjs +++ b/packages/astro/test/fixtures/core-image-errors/astro.config.mjs @@ -2,8 +2,4 @@ import { defineConfig } from 'astro/config'; export default defineConfig({ - legacy: { - // Needed because we're using image().refine() - collections: true, - }, }); diff --git a/packages/astro/test/fixtures/core-image/astro.config.mjs b/packages/astro/test/fixtures/core-image/astro.config.mjs index c628127e1fd5..74703959f216 100644 --- a/packages/astro/test/fixtures/core-image/astro.config.mjs +++ b/packages/astro/test/fixtures/core-image/astro.config.mjs @@ -2,8 +2,4 @@ import { defineConfig } from 'astro/config'; export default defineConfig({ - legacy: { - // Needed because we're using image().refine() - collections: true, - }, }); diff --git a/packages/astro/test/fixtures/core-image/src/content/blog/one.md b/packages/astro/test/fixtures/core-image/src/content/blog/one.md index 1ddcce919440..3312583d2f59 100644 --- a/packages/astro/test/fixtures/core-image/src/content/blog/one.md +++ b/packages/astro/test/fixtures/core-image/src/content/blog/one.md @@ -6,7 +6,6 @@ cover: arrayOfImages: - ../../assets/penguin2.jpg - ../../assets/penguin1.jpg -refinedImage: ../../assets/penguin1.jpg --- # A post diff --git a/packages/astro/test/fixtures/core-image/src/content/config.ts b/packages/astro/test/fixtures/core-image/src/content/config.ts index 2d88c49eee36..f2699e070867 100644 --- a/packages/astro/test/fixtures/core-image/src/content/config.ts +++ b/packages/astro/test/fixtures/core-image/src/content/config.ts @@ -8,7 +8,6 @@ const blogCollection = defineCollection({ image: image() }), arrayOfImages: z.array(image()), - refinedImage: image().refine((img) => img.width > 200) }), }); diff --git a/packages/astro/test/fixtures/core-image/src/pages/blog/[...slug].astro b/packages/astro/test/fixtures/core-image/src/pages/blog/[...slug].astro index dcf329ec423a..36d0d5ac9550 100644 --- a/packages/astro/test/fixtures/core-image/src/pages/blog/[...slug].astro +++ b/packages/astro/test/fixtures/core-image/src/pages/blog/[...slug].astro @@ -34,10 +34,6 @@ const myImage = await getImage({src: entry.data.image}); } -
- -
-
diff --git a/packages/astro/test/fixtures/css-inline-stylesheets-2/astro.config.mjs b/packages/astro/test/fixtures/css-inline-stylesheets-2/astro.config.mjs index 8ccbbc5b173c..afdd192283fa 100644 --- a/packages/astro/test/fixtures/css-inline-stylesheets-2/astro.config.mjs +++ b/packages/astro/test/fixtures/css-inline-stylesheets-2/astro.config.mjs @@ -1,8 +1,5 @@ import { defineConfig } from 'astro/config'; export default defineConfig({ - legacy: { - // Enable legacy content collections as we test layout fields - collections: true - } + }); diff --git a/packages/astro/test/fixtures/css-inline-stylesheets-2/src/content/en/endeavour.md b/packages/astro/test/fixtures/css-inline-stylesheets-2/src/content/en/endeavour.md index 240eeeae3993..428698f3a820 100644 --- a/packages/astro/test/fixtures/css-inline-stylesheets-2/src/content/en/endeavour.md +++ b/packages/astro/test/fixtures/css-inline-stylesheets-2/src/content/en/endeavour.md @@ -2,7 +2,6 @@ title: Endeavour description: 'Learn about the Endeavour NASA space shuttle.' publishedDate: 'Sun Jul 11 2021 00:00:00 GMT-0400 (Eastern Daylight Time)' -layout: '../../layouts/Layout.astro' tags: [space, 90s] --- diff --git a/packages/astro/test/fixtures/css-inline-stylesheets-3/astro.config.mjs b/packages/astro/test/fixtures/css-inline-stylesheets-3/astro.config.mjs index 8ccbbc5b173c..afdd192283fa 100644 --- a/packages/astro/test/fixtures/css-inline-stylesheets-3/astro.config.mjs +++ b/packages/astro/test/fixtures/css-inline-stylesheets-3/astro.config.mjs @@ -1,8 +1,5 @@ import { defineConfig } from 'astro/config'; export default defineConfig({ - legacy: { - // Enable legacy content collections as we test layout fields - collections: true - } + }); diff --git a/packages/astro/test/fixtures/css-inline-stylesheets-3/src/content/en/endeavour.md b/packages/astro/test/fixtures/css-inline-stylesheets-3/src/content/en/endeavour.md index 240eeeae3993..51d6e8c42178 100644 --- a/packages/astro/test/fixtures/css-inline-stylesheets-3/src/content/en/endeavour.md +++ b/packages/astro/test/fixtures/css-inline-stylesheets-3/src/content/en/endeavour.md @@ -2,7 +2,6 @@ title: Endeavour description: 'Learn about the Endeavour NASA space shuttle.' publishedDate: 'Sun Jul 11 2021 00:00:00 GMT-0400 (Eastern Daylight Time)' -layout: '../../layouts/Layout.astro' tags: [space, 90s] --- @@ -12,4 +11,4 @@ Space Shuttle Endeavour (Orbiter Vehicle Designation: OV-105) is a retired orbit The United States Congress approved the construction of Endeavour in 1987 to replace the Space Shuttle Challenger, which was destroyed in 1986. -NASA chose, on cost grounds, to build much of Endeavour from spare parts rather than refitting the Space Shuttle Enterprise, and used structural spares built during the construction of Discovery and Atlantis in its assembly. \ No newline at end of file +NASA chose, on cost grounds, to build much of Endeavour from spare parts rather than refitting the Space Shuttle Enterprise, and used structural spares built during the construction of Discovery and Atlantis in its assembly. diff --git a/packages/astro/test/fixtures/css-inline-stylesheets/astro.config.mjs b/packages/astro/test/fixtures/css-inline-stylesheets/astro.config.mjs index 8ccbbc5b173c..20b0b8e2ba7f 100644 --- a/packages/astro/test/fixtures/css-inline-stylesheets/astro.config.mjs +++ b/packages/astro/test/fixtures/css-inline-stylesheets/astro.config.mjs @@ -1,8 +1,4 @@ import { defineConfig } from 'astro/config'; export default defineConfig({ - legacy: { - // Enable legacy content collections as we test layout fields - collections: true - } }); diff --git a/packages/astro/test/fixtures/css-inline-stylesheets/src/content/en/endeavour.md b/packages/astro/test/fixtures/css-inline-stylesheets/src/content/en/endeavour.md index 240eeeae3993..428698f3a820 100644 --- a/packages/astro/test/fixtures/css-inline-stylesheets/src/content/en/endeavour.md +++ b/packages/astro/test/fixtures/css-inline-stylesheets/src/content/en/endeavour.md @@ -2,7 +2,6 @@ title: Endeavour description: 'Learn about the Endeavour NASA space shuttle.' publishedDate: 'Sun Jul 11 2021 00:00:00 GMT-0400 (Eastern Daylight Time)' -layout: '../../layouts/Layout.astro' tags: [space, 90s] --- diff --git a/packages/astro/test/legacy-content-collections.test.js b/packages/astro/test/legacy-content-collections.test.js deleted file mode 100644 index e4327ceb3de9..000000000000 --- a/packages/astro/test/legacy-content-collections.test.js +++ /dev/null @@ -1,456 +0,0 @@ -import assert from 'node:assert/strict'; -import { before, describe, it } from 'node:test'; -import * as cheerio from 'cheerio'; -import * as devalue from 'devalue'; -import testAdapter from './test-adapter.js'; -import { preventNodeBuiltinDependencyPlugin } from './test-plugins.js'; -import { loadFixture } from './test-utils.js'; - -describe('Legacy Content Collections', () => { - describe('Query', () => { - let fixture; - before(async () => { - fixture = await loadFixture({ root: './fixtures/legacy-content-collections/' }); - await fixture.build(); - }); - - describe('Collection', () => { - let json; - before(async () => { - const rawJson = await fixture.readFile('/collections.json'); - json = devalue.parse(rawJson); - }); - - it('Returns `without config` collection', async () => { - assert.ok(json.hasOwnProperty('withoutConfig')); - assert.equal(Array.isArray(json.withoutConfig), true); - - const ids = json.withoutConfig.map((item) => item.id); - assert.deepEqual( - ids.sort(), - [ - 'columbia.md', - 'endeavour.md', - 'enterprise.md', - // Spaces allowed in IDs - 'promo/launch week.mdx', - ].sort(), - ); - }); - - it('Handles spaces in `without config` slugs', async () => { - assert.ok(json.hasOwnProperty('withoutConfig')); - assert.equal(Array.isArray(json.withoutConfig), true); - - const slugs = json.withoutConfig.map((item) => item.slug); - assert.deepEqual( - slugs.sort(), - [ - 'columbia', - 'endeavour', - 'enterprise', - // "launch week.mdx" is converted to "launch-week.mdx" - 'promo/launch-week', - ].sort(), - ); - }); - - it('Passes legacy entry to filter function', async () => { - assert.ok(json.hasOwnProperty('filtered')); - assert.ok(Array.isArray(json.filtered)); - assert.ok(json.filtered.length > 0); - }); - - it('Returns `with schema` collection', async () => { - assert.ok(json.hasOwnProperty('withSchemaConfig')); - assert.equal(Array.isArray(json.withSchemaConfig), true); - - const ids = json.withSchemaConfig.map((item) => item.id); - const publishedDates = json.withSchemaConfig.map((item) => item.data.publishedAt); - assert.deepEqual(ids.sort(), ['four%.md', 'one.md', 'three.md', 'two.md'].sort()); - assert.equal( - publishedDates.every((date) => date instanceof Date), - true, - 'Not all publishedAt dates are Date objects', - ); - assert.deepEqual( - publishedDates.map((date) => date.toISOString()), - [ - '2021-01-01T00:00:00.000Z', - '2021-01-01T00:00:00.000Z', - '2021-01-03T00:00:00.000Z', - '2021-01-02T00:00:00.000Z', - ], - ); - }); - - it('Returns `with custom slugs` collection', async () => { - assert.ok(json.hasOwnProperty('withSlugConfig')); - assert.equal(Array.isArray(json.withSlugConfig), true); - - const slugs = json.withSlugConfig.map((item) => item.slug); - assert.deepEqual(slugs, ['fancy-one', 'excellent-three', 'interesting-two']); - }); - - it('Returns `with union schema` collection', async () => { - assert.ok(json.hasOwnProperty('withUnionSchema')); - assert.equal(Array.isArray(json.withUnionSchema), true); - - const post = json.withUnionSchema.find((item) => item.id === 'post.md'); - assert.notEqual(post, undefined); - assert.deepEqual(post.data, { - type: 'post', - title: 'My Post', - description: 'This is my post', - }); - const newsletter = json.withUnionSchema.find((item) => item.id === 'newsletter.md'); - assert.notEqual(newsletter, undefined); - assert.deepEqual(newsletter.data, { - type: 'newsletter', - subject: 'My Newsletter', - }); - }); - - it('Handles symlinked content', async () => { - assert.ok(json.hasOwnProperty('withSymlinkedContent')); - assert.equal(Array.isArray(json.withSymlinkedContent), true); - const ids = json.withSymlinkedContent.map((item) => item.id); - assert.deepEqual(ids.sort(), ['first.md', 'second.md', 'third.md'].sort()); - assert.equal( - json.withSymlinkedContent.find(({ id }) => id === 'first.md').data.title, - 'First Blog', - ); - }); - - it('Handles symlinked data', async () => { - assert.ok(json.hasOwnProperty('withSymlinkedData')); - assert.equal(Array.isArray(json.withSymlinkedData), true); - - const ids = json.withSymlinkedData.map((item) => item.id); - assert.deepEqual(ids, ['welcome']); - assert.equal( - json.withSymlinkedData[0].data.alt, - 'Futuristic landscape with chrome buildings and blue skies', - ); - assert.notEqual(json.withSymlinkedData[0].data.src.src, undefined); - }); - }); - - describe('Propagation', () => { - it('Applies styles', async () => { - const html = await fixture.readFile('/propagation/index.html'); - const $ = cheerio.load(html); - assert.equal($('style').text().includes('content:"works!"'), true); - }); - }); - - describe('Entry', () => { - let json; - before(async () => { - const rawJson = await fixture.readFile('/entries.json'); - json = devalue.parse(rawJson); - }); - - it('Returns `without config` collection entry', async () => { - assert.ok(json.hasOwnProperty('columbiaWithoutConfig')); - assert.equal(json.columbiaWithoutConfig.id, 'columbia.md'); - }); - - it('Returns `with schema` collection entry', async () => { - assert.ok(json.hasOwnProperty('oneWithSchemaConfig')); - assert.equal(json.oneWithSchemaConfig.id, 'one.md'); - assert.equal(json.oneWithSchemaConfig.data.publishedAt instanceof Date, true); - assert.equal( - json.oneWithSchemaConfig.data.publishedAt.toISOString(), - '2021-01-01T00:00:00.000Z', - ); - }); - - it('Returns `with custom slugs` collection entry', async () => { - assert.ok(json.hasOwnProperty('twoWithSlugConfig')); - assert.equal(json.twoWithSlugConfig.slug, 'interesting-two'); - }); - - it('Returns `with union schema` collection entry', async () => { - assert.ok(json.hasOwnProperty('postWithUnionSchema')); - assert.equal(json.postWithUnionSchema.id, 'post.md'); - assert.deepEqual(json.postWithUnionSchema.data, { - type: 'post', - title: 'My Post', - description: 'This is my post', - }); - }); - }); - - describe('Scripts', () => { - it('Contains all the scripts imported by components', async () => { - const html = await fixture.readFile('/with-scripts/one/index.html'); - const $ = cheerio.load(html); - assert.equal($('script').length, 2); - // Read the scripts' content - const scriptsCode = $('script') - .map((_, el) => $(el).text()) - .toArray() - .join('\n'); - assert.match(scriptsCode, /ScriptCompA/); - assert.match(scriptsCode, /ScriptCompB/); - }); - }); - }); - - const blogSlugToContents = { - 'first-post': { - title: 'First post', - element: 'blockquote', - content: 'First post loaded: yes!', - }, - 'second-post': { - title: 'Second post', - element: 'blockquote', - content: 'Second post loaded: yes!', - }, - 'third-post': { - title: 'Third post', - element: 'blockquote', - content: 'Third post loaded: yes!', - }, - 'using-mdx': { - title: 'Using MDX', - element: 'a[href="#"]', - content: 'Embedded component in MDX', - }, - }; - - describe('Static paths integration', () => { - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: './fixtures/content-static-paths-integration/', - legacy: { - collections: true, - }, - }); - await fixture.build(); - }); - - it('Generates expected pages', async () => { - for (const slug in blogSlugToContents) { - assert.equal(fixture.pathExists(`/posts/${slug}`), true); - } - }); - - it('Renders titles', async () => { - for (const slug in blogSlugToContents) { - const post = await fixture.readFile(`/posts/${slug}/index.html`); - const $ = cheerio.load(post); - assert.equal($('h1').text(), blogSlugToContents[slug].title); - } - }); - - it('Renders content', async () => { - for (const slug in blogSlugToContents) { - const post = await fixture.readFile(`/posts/${slug}/index.html`); - const $ = cheerio.load(post); - assert.equal( - $(blogSlugToContents[slug].element).text().trim(), - blogSlugToContents[slug].content, - ); - } - }); - }); - - describe('With spaces in path', () => { - it('Does not throw', async () => { - const fixture = await loadFixture({ - root: './fixtures/content with spaces in folder name/', - legacy: { - collections: true, - }, - }); - let error = null; - try { - await fixture.build({ force: true }); - } catch (e) { - error = e.message; - } - assert.equal(error, null); - }); - }); - describe('With config.mjs', () => { - it("Errors when frontmatter doesn't match schema", async () => { - const fixture = await loadFixture({ - root: './fixtures/content-collections-with-config-mjs/', - legacy: { - collections: true, - }, - }); - let error; - try { - await fixture.build(); - } catch (e) { - error = e.message; - } - assert.match(error, /\*\*title\*\*: Expected type `"string"`, received `"number"`/); - }); - }); - describe('With config.mts', () => { - it("Errors when frontmatter doesn't match schema", async () => { - const fixture = await loadFixture({ - root: './fixtures/content-collections-with-config-mts/', - legacy: { - collections: true, - }, - }); - let error; - try { - await fixture.build(); - } catch (e) { - error = e.message; - } - assert.match(error, /\*\*title\*\*: Expected type `"string"`, received `"number"`/); - }); - }); - - describe('With empty markdown file', () => { - it('Throws the right error', async () => { - const fixture = await loadFixture({ - root: './fixtures/content-collections-empty-md-file/', - legacy: { - collections: true, - }, - }); - let error; - try { - await fixture.build(); - } catch (e) { - error = e.message; - } - assert.equal(error.includes('**title**: Required'), true); - }); - }); - - describe('With empty collections directory', () => { - it('Handles the empty directory correctly', async () => { - const fixture = await loadFixture({ - root: './fixtures/content-collections-empty-dir/', - legacy: { - collections: true, - }, - }); - let error; - try { - await fixture.build(); - } catch (e) { - error = e.message; - } - assert.equal(error, undefined); - - const html = await fixture.readFile('/index.html'); - const $ = cheerio.load(html); - const h1 = $('h1'); - assert.equal(h1.text(), 'Entries length: 0'); - assert.equal(h1.attr('data-entries'), '[]'); - }); - }); - - describe('SSR integration', () => { - let app; - - before(async () => { - const fixture = await loadFixture({ - root: './fixtures/content-ssr-integration/', - output: 'server', - adapter: testAdapter(), - vite: { - plugins: [preventNodeBuiltinDependencyPlugin()], - }, - legacy: { - collections: true, - }, - }); - await fixture.build(); - app = await fixture.loadTestAdapterApp(); - }); - - it('Responds 200 for expected pages', async () => { - for (const slug in blogSlugToContents) { - const request = new Request('http://example.com/posts/' + slug); - const response = await app.render(request); - assert.equal(response.status, 200); - } - }); - - it('Renders titles', async () => { - for (const slug in blogSlugToContents) { - const request = new Request('http://example.com/posts/' + slug); - const response = await app.render(request); - const body = await response.text(); - const $ = cheerio.load(body); - assert.equal($('h1').text(), blogSlugToContents[slug].title); - } - }); - - it('Renders content', async () => { - for (const slug in blogSlugToContents) { - const request = new Request('http://example.com/posts/' + slug); - const response = await app.render(request); - const body = await response.text(); - const $ = cheerio.load(body); - assert.equal( - $(blogSlugToContents[slug].element).text().trim(), - blogSlugToContents[slug].content, - ); - } - }); - }); - - describe('Base configuration', () => { - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: './fixtures/content-collections-base/', - legacy: { - collections: true, - }, - }); - await fixture.build(); - }); - - it('Includes base in links', async () => { - const html = await fixture.readFile('/docs/index.html'); - const $ = cheerio.load(html); - assert.equal($('link').attr('href').startsWith('/docs'), true); - }); - - it('Includes base in scripts', async () => { - const html = await fixture.readFile('/docs/index.html'); - const $ = cheerio.load(html); - assert.equal($('script').attr('src').startsWith('/docs'), true); - }); - }); - - describe('Mutation', () => { - let fixture; - - before(async () => { - fixture = await loadFixture({ - root: './fixtures/content-collections-mutation/', - legacy: { - collections: true, - }, - }); - await fixture.build(); - }); - - it('Does not mutate cached collection', async () => { - const html = await fixture.readFile('/index.html'); - const index = cheerio.load(html)('h2:first').text(); - const html2 = await fixture.readFile('/another_page/index.html'); - const anotherPage = cheerio.load(html2)('h2:first').text(); - - assert.equal(index, anotherPage); - }); - }); -}); diff --git a/packages/astro/test/legacy-data-collections.test.js b/packages/astro/test/legacy-data-collections.test.js deleted file mode 100644 index 6bd5f19493c9..000000000000 --- a/packages/astro/test/legacy-data-collections.test.js +++ /dev/null @@ -1,159 +0,0 @@ -import assert from 'node:assert/strict'; -import { before, describe, it } from 'node:test'; -import { loadFixture } from './test-utils.js'; - -const authorIds = ['Ben Holmes', 'Fred K Schott', 'Nate Moore']; -const translationIds = ['en', 'es', 'fr']; - -describe('Content Collections - legacy data collections', () => { - let fixture; - before(async () => { - fixture = await loadFixture({ root: './fixtures/legacy-data-collections/' }); - await fixture.build({ force: true }); - }); - - describe('Authors Collection', () => { - let json; - before(async () => { - const rawJson = await fixture.readFile('/authors/all.json'); - json = JSON.parse(rawJson); - }); - - it('Returns', async () => { - assert.equal(Array.isArray(json), true); - assert.equal(json.length, 3); - }); - - it('Generates correct ids', async () => { - const ids = json.map((item) => item.id).sort(); - assert.deepEqual(ids, ['Ben Holmes', 'Fred K Schott', 'Nate Moore']); - }); - - it('Generates correct data', async () => { - const names = json.map((item) => item.data.name); - assert.deepEqual(names, ['Ben J Holmes', 'Fred K Schott', 'Nate Something Moore']); - - const twitterUrls = json.map((item) => item.data.twitter); - assert.deepEqual(twitterUrls, [ - 'https://twitter.com/bholmesdev', - 'https://twitter.com/FredKSchott', - 'https://twitter.com/n_moore', - ]); - }); - }); - - describe('getDataEntryById', () => { - let json; - before(async () => { - const rawJson = await fixture.readFile('/translations/by-id.json'); - json = JSON.parse(rawJson); - }); - it('Grabs the item by the base file name', () => { - assert.equal(json.id, 'en'); - }); - }); - - describe('Authors Entry', () => { - for (const authorId of authorIds) { - let json; - before(async () => { - const rawJson = await fixture.readFile(`/authors/${authorId}.json`); - json = JSON.parse(rawJson); - }); - - it(`Returns ${authorId}`, async () => { - assert.equal(json.hasOwnProperty('id'), true); - assert.equal(json.id, authorId); - }); - - it(`Generates correct data for ${authorId}`, async () => { - assert.equal(json.hasOwnProperty('data'), true); - assert.equal(json.data.hasOwnProperty('name'), true); - assert.equal(json.data.hasOwnProperty('twitter'), true); - - switch (authorId) { - case 'Ben Holmes': - assert.equal(json.data.name, 'Ben J Holmes'); - assert.equal(json.data.twitter, 'https://twitter.com/bholmesdev'); - break; - case 'Fred K Schott': - assert.equal(json.data.name, 'Fred K Schott'); - assert.equal(json.data.twitter, 'https://twitter.com/FredKSchott'); - break; - case 'Nate Moore': - assert.equal(json.data.name, 'Nate Something Moore'); - assert.equal(json.data.twitter, 'https://twitter.com/n_moore'); - break; - } - }); - } - }); - - describe('Translations Collection', () => { - let json; - before(async () => { - const rawJson = await fixture.readFile('/translations/all.json'); - json = JSON.parse(rawJson); - }); - - it('Returns', async () => { - assert.equal(Array.isArray(json), true); - assert.equal(json.length, 3); - }); - - it('Generates correct ids', async () => { - const ids = json.map((item) => item.id).sort(); - assert.deepEqual(ids, translationIds); - }); - - it('Generates correct data', async () => { - const sorted = json.sort((a, b) => a.id.localeCompare(b.id)); - const homepageGreetings = sorted.map((item) => item.data.homepage?.greeting); - assert.deepEqual(homepageGreetings, ['Hello World!', 'ยกHola Mundo!', 'Bonjour le monde!']); - - const homepagePreambles = sorted.map((item) => item.data.homepage?.preamble); - assert.deepEqual(homepagePreambles, [ - 'Welcome to the future of content.', - 'Bienvenido al futuro del contenido.', - 'Bienvenue dans le futur du contenu.', - ]); - }); - }); - - describe('Translations Entry', () => { - for (const translationId of translationIds) { - let json; - before(async () => { - const rawJson = await fixture.readFile(`/translations/${translationId}.json`); - json = JSON.parse(rawJson); - }); - - it(`Returns ${translationId}`, async () => { - assert.equal(json.hasOwnProperty('id'), true); - assert.equal(json.id, translationId); - }); - - it(`Generates correct data for ${translationId}`, async () => { - assert.equal(json.hasOwnProperty('data'), true); - assert.equal(json.data.hasOwnProperty('homepage'), true); - assert.equal(json.data.homepage.hasOwnProperty('greeting'), true); - assert.equal(json.data.homepage.hasOwnProperty('preamble'), true); - - switch (translationId) { - case 'en': - assert.equal(json.data.homepage.greeting, 'Hello World!'); - assert.equal(json.data.homepage.preamble, 'Welcome to the future of content.'); - break; - case 'es': - assert.equal(json.data.homepage.greeting, 'ยกHola Mundo!'); - assert.equal(json.data.homepage.preamble, 'Bienvenido al futuro del contenido.'); - break; - case 'fr': - assert.equal(json.data.homepage.greeting, 'Bonjour le monde!'); - assert.equal(json.data.homepage.preamble, 'Bienvenue dans le futur du contenu.'); - break; - } - }); - } - }); -}); diff --git a/packages/astro/test/units/dev/collections-mixed-content-errors.test.js b/packages/astro/test/units/dev/collections-mixed-content-errors.test.js deleted file mode 100644 index 295662c93110..000000000000 --- a/packages/astro/test/units/dev/collections-mixed-content-errors.test.js +++ /dev/null @@ -1,147 +0,0 @@ -import * as assert from 'node:assert/strict'; -import { describe, it } from 'node:test'; -import _sync from '../../../dist/core/sync/index.js'; -import { createFixture } from '../test-utils.js'; - -async function sync(root) { - try { - await _sync({ - root, - logLevel: 'silent', - }); - return 0; - } catch { - return 1; - } -} - -const baseFileTree = { - '/astro.config.mjs': `export default { legacy: { collections: true }}`, - '/src/content/authors/placeholder.json': `{ "name": "Placeholder" }`, - '/src/content/blog/placeholder.md': `\ ---- -title: Placeholder post ---- -`, - '/src/pages/authors.astro': `\ ---- -import { getCollection } from 'astro:content'; -try { - await getCollection('authors') -} catch (e) { - return e -} ---- - -

Worked

-`, - '/src/pages/blog.astro': `\ ---- -import { getCollection } from 'astro:content'; - -await getCollection('blog') ---- - -

Worked

`, -}; - -describe('Content Collections - mixed content errors', () => { - it('raises "mixed content" error when content in data collection', async () => { - const fixture = await createFixture({ - ...baseFileTree, - '/src/content/authors/ben.md': `\ ---- -name: Ben ---- - -# Ben -`, - '/src/content/authors/tony.json': `{ "name": "Tony" }`, - '/src/content.config.ts': `\ -import { z, defineCollection } from 'astro:content'; - -const authors = defineCollection({ - type: 'data', - schema: z.object({ - name: z.string(), - }), -}); - -export const collections = { authors }; -`, - }); - - assert.equal(await sync(fixture.path), 1); - }); - - it('raises "mixed content" error when data in content collection', async () => { - const fixture = await createFixture({ - ...baseFileTree, - '/src/content/blog/post.md': `\ ---- -title: Post ---- - -# Post -`, - '/src/content/blog/post.yaml': `title: YAML Post`, - '/src/content.config.ts': `\ -import { z, defineCollection } from 'astro:content'; - -const blog = defineCollection({ - type: 'content', - schema: z.object({ - title: z.string(), - }), -}); - -export const collections = { blog }; -`, - }); - - assert.equal(await sync(fixture.path), 1); - }); - - it('raises error when data collection configured as content collection', async () => { - const fixture = await createFixture({ - ...baseFileTree, - '/src/content/banners/welcome.json': `{ "src": "/example", "alt": "Welcome" }`, - '/src/content/config.ts': `\ -import { z, defineCollection } from 'astro:content'; - -const banners = defineCollection({ - schema: z.object({ - src: z.string(), - alt: z.string(), - }), -}); - -export const collections = { banners }; -`, - }); - - assert.equal(await sync(fixture.path), 1); - }); - - it('does not raise error for empty collection with config', async () => { - const fixture = await createFixture({ - ...baseFileTree, - // Add placeholder to ensure directory exists - '/src/content/i18n/_placeholder.txt': 'Need content here', - '/src/content.config.ts': `\ -import { z, defineCollection } from 'astro:content'; - -const i18n = defineCollection({ - type: 'data', - schema: z.object({ - greeting: z.string(), - }), -}); - -export const collections = { i18n }; -`, - }); - - assert.equal(await sync(fixture.path), 0); - }); -}); diff --git a/packages/astro/test/units/dev/collections-renderentry.test.js b/packages/astro/test/units/dev/collections-renderentry.test.js deleted file mode 100644 index 298c433b8b16..000000000000 --- a/packages/astro/test/units/dev/collections-renderentry.test.js +++ /dev/null @@ -1,298 +0,0 @@ -import * as assert from 'node:assert/strict'; -import { describe, it } from 'node:test'; -import * as cheerio from 'cheerio'; - -import { attachContentServerListeners } from '../../../dist/content/server-listeners.js'; -import { createFixture, createRequestAndResponse, runInContainer } from '../test-utils.js'; - -const baseFileTree = { - 'astro.config.mjs': `\ -import mdx from '@astrojs/mdx'; -export default { - integrations: [mdx()], - legacy: { - // Enable legacy content collections as we test layout fields - collections: true - } -}; -`, - '/src/content/blog/promo/_launch-week-styles.css': `\ -body { - font-family: 'Comic Sans MS', sans-serif; -} -`, - '/src/content/blog/promo/launch-week.mdx': `\ ---- -title: 'Launch week!' -description: 'Join us for the exciting launch of SPACE BLOG' -publishedDate: 'Sat May 21 2022 00:00:00 GMT-0400 (Eastern Daylight Time)' -tags: ['announcement'] ---- - -import './_launch-week-styles.css'; - -Join us for the space blog launch! - -- THIS THURSDAY -- Houston, TX -- Dress code: **interstellar casual** โœจ -`, -}; - -/** @type {typeof runInContainer} */ -async function runInContainerWithContentListeners(params, callback) { - return await runInContainer(params, async (container) => { - await attachContentServerListeners(container); - await callback(container); - }); -} - -describe('Content Collections - render()', () => { - it('can be called in a page component', async () => { - const fixture = await createFixture({ - ...baseFileTree, - '/src/content/config.ts': ` - import { z, defineCollection } from 'astro:content'; - - const blog = defineCollection({ - schema: z.object({ - title: z.string(), - description: z.string().max(60, 'For SEO purposes, keep descriptions short!'), - }), - }); - - export const collections = { blog }; - `, - '/src/pages/index.astro': ` - --- - import { getCollection } from 'astro:content'; - const blog = await getCollection('blog'); - const launchWeekEntry = blog.find(post => post.id === 'promo/launch-week.mdx'); - const { Content } = await launchWeekEntry.render(); - --- - - Testing - -

testing

- - - - `, - }); - - await runInContainerWithContentListeners( - { - inlineConfig: { - root: fixture.path, - vite: { server: { middlewareMode: true } }, - }, - }, - async (container) => { - const { req, res, done, text } = createRequestAndResponse({ - method: 'GET', - url: '/', - }); - container.handle(req, res); - await done; - const html = await text(); - - const $ = cheerio.load(html); - // Rendered the content - assert.equal($('ul li').length, 3); - - // Rendered the styles - assert.equal($('style').length, 1); - }, - ); - }); - - it('can be used in a layout component', async () => { - const fixture = await createFixture({ - ...baseFileTree, - '/src/components/Layout.astro': ` - --- - import { getCollection } from 'astro:content'; - const blog = await getCollection('blog'); - const launchWeekEntry = blog.find(post => post.id === 'promo/launch-week.mdx'); - const { Content } = await launchWeekEntry.render(); - --- - - - - -
- -
- - - - `, - '/src/pages/index.astro': ` - --- - import Layout from '../components/Layout.astro'; - --- - -

Index page

-
- `, - }); - - await runInContainerWithContentListeners( - { - inlineConfig: { - root: fixture.path, - vite: { server: { middlewareMode: true } }, - }, - }, - async (container) => { - const { req, res, done, text } = createRequestAndResponse({ - method: 'GET', - url: '/', - }); - container.handle(req, res); - await done; - const html = await text(); - - const $ = cheerio.load(html); - // Rendered the content - assert.equal($('ul li').length, 3); - - // Rendered the styles - assert.equal($('style').length, 1); - }, - ); - }); - - it('can be used in a slot', async () => { - const fixture = await createFixture({ - ...baseFileTree, - '/src/content.config.ts': ` - import { z, defineCollection } from 'astro:content'; - - const blog = defineCollection({ - schema: z.object({ - title: z.string(), - description: z.string().max(60, 'For SEO purposes, keep descriptions short!'), - }), - }); - - export const collections = { blog }; - `, - '/src/components/Layout.astro': ` - - - - -
- -
- - - `, - '/src/pages/index.astro': ` - --- - import Layout from '../components/Layout.astro'; - import { getCollection } from 'astro:content'; - const blog = await getCollection('blog'); - const launchWeekEntry = blog.find(post => post.id === 'promo/launch-week.mdx'); - const { Content } = await launchWeekEntry.render(); - --- - -

Index page

- -
- `, - }); - - await runInContainerWithContentListeners( - { - inlineConfig: { - root: fixture.path, - vite: { server: { middlewareMode: true } }, - }, - }, - async (container) => { - const { req, res, done, text } = createRequestAndResponse({ - method: 'GET', - url: '/', - }); - container.handle(req, res); - await done; - const html = await text(); - - const $ = cheerio.load(html); - // Rendered the content - assert.equal($('ul li').length, 3); - - // Rendered the styles - assert.equal($('style').length, 1); - }, - ); - }); - - it('can be called from any js/ts file', async () => { - const fixture = await createFixture({ - ...baseFileTree, - '/src/content.config.ts': ` - import { z, defineCollection } from 'astro:content'; - - const blog = defineCollection({ - schema: z.object({ - title: z.string(), - description: z.string().max(60, 'For SEO purposes, keep descriptions short!'), - }), - }); - - export const collections = { blog }; - `, - '/src/launch-week.ts': ` - import { getCollection } from 'astro:content'; - - export let Content; - - const blog = await getCollection('blog'); - const launchWeekEntry = blog.find(post => post.id === 'promo/launch-week.mdx'); - const mod = await launchWeekEntry.render(); - - Content = mod.Content; - `, - '/src/pages/index.astro': ` - --- - import { Content } from '../launch-week.ts'; - --- - - Testing - -

Testing

- - - - `, - }); - - await runInContainerWithContentListeners( - { - inlineConfig: { - root: fixture.path, - vite: { server: { middlewareMode: true } }, - }, - }, - async (container) => { - const { req, res, done, text } = createRequestAndResponse({ - method: 'GET', - url: '/', - }); - container.handle(req, res); - await done; - const html = await text(); - - const $ = cheerio.load(html); - // Rendered the content - assert.equal($('ul li').length, 3); - - // Rendered the styles - assert.equal($('style').length, 1); - }, - ); - }); -}); From 2a17d15e29a3d4171b305e6c259f6541b17d2694 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Fri, 19 Sep 2025 16:20:29 +0100 Subject: [PATCH 02/19] wip: remove legacy content collection support --- .changeset/young-banks-camp.md | 5 + packages/astro/src/content/loaders/glob.ts | 9 - packages/astro/src/content/runtime.ts | 220 +++--------------- packages/astro/templates/content/module.mjs | 5 - .../test/content-collections-render.test.js | 2 +- .../src/pages/docs.astro | 6 +- .../src/pages/docs.astro | 6 +- .../src/pages/index.astro | 4 +- .../src/pages/index.astro | 4 +- .../content-collections/src/content.config.ts | 14 +- .../src/pages/entries.json.js | 8 +- .../src/pages/with-scripts/[...slug].astro | 6 +- .../{content/config.ts => content.config.ts} | 4 +- .../src/pages/posts/[...slug].astro | 6 +- .../src/pages/posts/[...slug].astro | 6 +- .../{content/config.ts => content.config.ts} | 4 +- .../pages/launch-week-component-scripts.astro | 6 +- .../pages/launch-week-components-export.astro | 6 +- .../content/src/pages/launch-week.astro | 7 +- .../content/src/pages/with-layout-prop.astro | 9 - .../core-image-base/src/content.config.ts | 2 + .../src/pages/blog/[...slug].astro | 6 +- .../core-image-deletion/src/content.config.ts | 3 +- .../src/pages/blog/[slug].astro | 6 +- .../{content/config.ts => content.config.ts} | 4 +- .../src/pages/blog/[...slug].astro | 6 +- .../core-image-ssg/src/content.config.ts | 2 + .../src/pages/blog/[...slug].astro | 6 +- .../{content/config.ts => content.config.ts} | 4 +- .../src/pages/blog/[...slug].astro | 6 +- .../{content/config.ts => content.config.ts} | 4 +- .../core-image/src/pages/blog/[...slug].astro | 6 +- .../src/pages/index.astro | 6 +- .../src/pages/index.astro | 6 +- .../src/pages/index.astro | 6 +- .../src/content.config.ts | 11 +- .../data-collections/src/content.config.ts | 7 +- .../src/pages/translations/by-id.json.js | 4 +- .../{content/config.ts => content.config.ts} | 12 +- .../src/pages/collections.json.js | 2 +- .../src/pages/with-scripts/[...slug].astro | 6 +- .../{content/config.ts => content.config.ts} | 7 +- .../src/pages/translations/by-id.json.js | 4 +- .../content-collections/frontmatter.test.js | 2 + 44 files changed, 162 insertions(+), 303 deletions(-) create mode 100644 .changeset/young-banks-camp.md rename packages/astro/test/fixtures/content-ssr-integration/src/{content/config.ts => content.config.ts} (64%) rename packages/astro/test/fixtures/content/src/{content/config.ts => content.config.ts} (59%) delete mode 100644 packages/astro/test/fixtures/content/src/pages/with-layout-prop.astro rename packages/astro/test/fixtures/core-image-errors/src/{content/config.ts => content.config.ts} (70%) rename packages/astro/test/fixtures/core-image-svg/src/{content/config.ts => content.config.ts} (59%) rename packages/astro/test/fixtures/core-image/src/{content/config.ts => content.config.ts} (73%) rename packages/astro/test/fixtures/legacy-content-collections/src/{content/config.ts => content.config.ts} (69%) rename packages/astro/test/fixtures/legacy-data-collections/src/{content/config.ts => content.config.ts} (54%) diff --git a/.changeset/young-banks-camp.md b/.changeset/young-banks-camp.md new file mode 100644 index 000000000000..9b23e58d5526 --- /dev/null +++ b/.changeset/young-banks-camp.md @@ -0,0 +1,5 @@ +--- +'astro': major +--- + +WIP diff --git a/packages/astro/src/content/loaders/glob.ts b/packages/astro/src/content/loaders/glob.ts index dca06479dbe8..a75458f095c2 100644 --- a/packages/astro/src/content/loaders/glob.ts +++ b/packages/astro/src/content/loaders/glob.ts @@ -232,11 +232,6 @@ export function glob(globOptions: GlobOptions): Loader { const contentDir = new URL('content/', config.srcDir); - function isInContentDir(file: string) { - const fileUrl = new URL(file, baseDir); - return fileUrl.href.startsWith(contentDir.href); - } - const configFiles = new Set( ['config.js', 'config.ts', 'config.mjs'].map((file) => new URL(file, contentDir).href), ); @@ -251,10 +246,6 @@ export function glob(globOptions: GlobOptions): Loader { if (isConfigFile(entry)) { return; } - if (isInContentDir(entry)) { - skippedFiles.push(entry); - return; - } return limit(async () => { const entryType = configForFile(entry); await syncData(entry, baseDir, entryType); diff --git a/packages/astro/src/content/runtime.ts b/packages/astro/src/content/runtime.ts index 87e29f21ed42..6154cf8a46c1 100644 --- a/packages/astro/src/content/runtime.ts +++ b/packages/astro/src/content/runtime.ts @@ -40,33 +40,11 @@ export { LiveCollectionValidationError, }; type LazyImport = () => Promise; -type GlobResult = Record; -type CollectionToEntryMap = Record; -type GetEntryImport = (collection: string, lookupId: string) => Promise; type LiveCollectionConfigMap = Record< string, { loader: LiveLoader; type: typeof LIVE_CONTENT_TYPE; schema?: z.ZodType } >; -export function createCollectionToGlobResultMap({ - globResult, - contentDir, -}: { - globResult: GlobResult; - contentDir: string; -}) { - const collectionToGlobResultMap: CollectionToEntryMap = {}; - for (const key in globResult) { - const keyRelativeToContentDir = key.replace(new RegExp(`^${contentDir}`), ''); - const segments = keyRelativeToContentDir.split('/'); - if (segments.length <= 1) continue; - const collection = segments[0]; - collectionToGlobResultMap[collection] ??= {}; - collectionToGlobResultMap[collection][key] = globResult[key]; - } - return collectionToGlobResultMap; -} - const cacheHintSchema = z.object({ tags: z.array(z.string()).optional(), maxAge: z.number().optional(), @@ -144,10 +122,6 @@ export function createGetCollection({ collection, }; - if (entry.legacyId) { - entry = emulateLegacyEntry(entry); - } - if (hasFilter && !filter(entry)) { continue; } @@ -165,94 +139,6 @@ export function createGetCollection({ }; } -export function createGetEntryBySlug({ - getEntryImport, - getRenderEntryImport, - collectionNames, - getEntry, -}: { - getEntryImport: GetEntryImport; - getRenderEntryImport: GetEntryImport; - collectionNames: Set; - getEntry: ReturnType; -}) { - return async function getEntryBySlug(collection: string, slug: string) { - const store = await globalDataStore.get(); - - if (!collectionNames.has(collection)) { - if (store.hasCollection(collection)) { - const entry = await getEntry(collection, slug); - if (entry && 'slug' in entry) { - return entry; - } - throw new AstroError({ - ...AstroErrorData.GetEntryDeprecationError, - message: AstroErrorData.GetEntryDeprecationError.message(collection, 'getEntryBySlug'), - }); - } - console.warn( - `The collection ${JSON.stringify(collection)} does not exist. Please ensure it is defined in your content config.`, - ); - return undefined; - } - - const entryImport = await getEntryImport(collection, slug); - if (typeof entryImport !== 'function') return undefined; - - const entry = await entryImport(); - - return { - id: entry.id, - slug: entry.slug, - body: entry.body, - collection: entry.collection, - data: entry.data, - async render() { - return render({ - collection: entry.collection, - id: entry.id, - renderEntryImport: await getRenderEntryImport(collection, slug), - }); - }, - }; - }; -} - -export function createGetDataEntryById({ - getEntryImport, - collectionNames, - getEntry, -}: { - getEntryImport: GetEntryImport; - collectionNames: Set; - getEntry: ReturnType; -}) { - return async function getDataEntryById(collection: string, id: string) { - const store = await globalDataStore.get(); - - if (!collectionNames.has(collection)) { - if (store.hasCollection(collection)) { - return getEntry(collection, id); - } - console.warn( - `The collection ${JSON.stringify(collection)} does not exist. Please ensure it is defined in your content config.`, - ); - return undefined; - } - - const lazyImport = await getEntryImport(collection, id); - - if (!lazyImport) throw new Error(`Entry ${collection} โ†’ ${id} was not found.`); - const entry = await lazyImport(); - - return { - id: entry.id, - collection: entry.collection, - data: entry.data, - }; - }; -} - type ContentEntryResult = { id: string; slug: string; @@ -270,31 +156,7 @@ type DataEntryResult = { type EntryLookupObject = { collection: string; id: string } | { collection: string; slug: string }; -function emulateLegacyEntry({ legacyId, ...entry }: DataEntry & { collection: string }) { - // Define this first so it's in scope for the render function - const legacyEntry = { - ...entry, - id: legacyId!, - slug: entry.id, - }; - return { - ...legacyEntry, - // Define separately so the render function isn't included in the object passed to `renderEntry()` - render: () => renderEntry(legacyEntry), - } as ContentEntryResult; -} - -export function createGetEntry({ - getEntryImport, - getRenderEntryImport, - collectionNames, - liveCollections, -}: { - getEntryImport: GetEntryImport; - getRenderEntryImport: GetEntryImport; - collectionNames: Set; - liveCollections: LiveCollectionConfigMap; -}) { +export function createGetEntry({ liveCollections }: { liveCollections: LiveCollectionConfigMap }) { return async function getEntry( // Can either pass collection and identifier as 2 positional args, // Or pass a single object with the collection and identifier as properties. @@ -344,53 +206,47 @@ export function createGetEntry({ // @ts-expect-error virtual module const { default: imageAssetMap } = await import('astro:asset-imports'); entry.data = updateImageReferencesInData(entry.data, entry.filePath, imageAssetMap); - if (entry.legacyId) { - return emulateLegacyEntry({ ...entry, collection }); - } - return { + const result = { ...entry, collection, } as DataEntryResult | ContentEntryResult; - } - - if (!collectionNames.has(collection)) { - console.warn( - `The collection ${JSON.stringify(collection)} does not exist. Please ensure it is defined in your content config.`, + warnForPropertyAccess( + result.data, + 'slug', + `[content] Attempted to access deprecated property on "${collection}" entry.\nThe "slug" property is no longer automatically added to entries. Please use the "id" property instead.`, ); - return undefined; + warnForPropertyAccess( + result, + 'render', + `[content] Invalid attempt to access "render()" method on "${collection}" entry.\nTo render an entry, use "render(entry)" from "astro:content".`, + ); + return result; } - const entryImport = await getEntryImport(collection, lookupId); - if (typeof entryImport !== 'function') return undefined; - - const entry = await entryImport(); - - if (entry._internal.type === 'content') { - return { - id: entry.id, - slug: entry.slug, - body: entry.body, - collection: entry.collection, - data: entry.data, - async render() { - return render({ - collection: entry.collection, - id: entry.id, - renderEntryImport: await getRenderEntryImport(collection, lookupId), - }); - }, - }; - } else if (entry._internal.type === 'data') { - return { - id: entry.id, - collection: entry.collection, - data: entry.data, - }; - } return undefined; }; } +function warnForPropertyAccess(entry: object, prop: string, message: string) { + // Skip if the property is already defined (it may be legitimately defined on the entry) + if (!(prop in entry)) { + let _value: any = undefined; + Object.defineProperty(entry, prop, { + get() { + // If the user sets value themselves, don't warn + if (_value === undefined) { + console.error(message); + } + return _value; + }, + set(v) { + _value = v; + }, + enumerable: false, + }); + } +} + export function createGetEntries(getEntry: ReturnType) { return async function getEntries( entries: { collection: string; id: string }[] | { collection: string; slug: string }[], @@ -681,21 +537,11 @@ function updateImageReferencesInData>( }); } -export async function renderEntry( - entry: - | DataEntry - | { render: () => Promise<{ Content: AstroComponentFactory }> } - | (DataEntry & { render: () => Promise<{ Content: AstroComponentFactory }> }), -) { +export async function renderEntry(entry: DataEntry) { if (!entry) { throw new AstroError(AstroErrorData.RenderUndefinedEntryError); } - if ('render' in entry && !('legacyId' in entry)) { - // This is an old content collection entry, so we use its render method - return entry.render(); - } - if (entry.deferredRender) { try { // @ts-expect-error virtual module diff --git a/packages/astro/templates/content/module.mjs b/packages/astro/templates/content/module.mjs index bfd8e95c90fc..35e64af24dda 100644 --- a/packages/astro/templates/content/module.mjs +++ b/packages/astro/templates/content/module.mjs @@ -1,11 +1,8 @@ // astro-head-inject import { - createCollectionToGlobResultMap, createGetCollection, - createGetDataEntryById, createGetEntries, createGetEntry, - createGetEntryBySlug, createGetLiveCollection, createGetLiveEntry, createReference, @@ -20,8 +17,6 @@ export { z } from 'astro/zod'; /* @@LIVE_CONTENT_CONFIG@@ */ - -const cacheEntriesByCollection = new Map(); export const getCollection = createGetCollection({ liveCollections, }); diff --git a/packages/astro/test/content-collections-render.test.js b/packages/astro/test/content-collections-render.test.js index 607d1f9eefea..c121f7b75f74 100644 --- a/packages/astro/test/content-collections-render.test.js +++ b/packages/astro/test/content-collections-render.test.js @@ -213,7 +213,7 @@ describe('Content Collections - render()', () => { assert.equal(h2.attr('data-components-export-applied'), 'true'); }); - it('Supports layout prop with recursive getCollection() call', async () => { + it.skip('Supports layout prop with recursive getCollection() call - DEPRECATED: layout props removed in Astro 5', async () => { const response = await fixture.fetch('/with-layout-prop', { method: 'GET' }); assert.equal(response.status, 200); diff --git a/packages/astro/test/fixtures/content-collections-base/src/pages/docs.astro b/packages/astro/test/fixtures/content-collections-base/src/pages/docs.astro index 6b352ce371a8..a57364f8633c 100644 --- a/packages/astro/test/fixtures/content-collections-base/src/pages/docs.astro +++ b/packages/astro/test/fixtures/content-collections-base/src/pages/docs.astro @@ -1,7 +1,7 @@ --- -import { getEntryBySlug } from 'astro:content'; -const entry = await getEntryBySlug('docs', 'one'); -const { Content } = await entry.render(); +import { getEntry, render } from 'astro:content'; +const entry = await getEntry('docs', 'one'); +const { Content } = await render(entry); --- diff --git a/packages/astro/test/fixtures/content-collections-same-contents/src/pages/docs.astro b/packages/astro/test/fixtures/content-collections-same-contents/src/pages/docs.astro index 6b352ce371a8..a57364f8633c 100644 --- a/packages/astro/test/fixtures/content-collections-same-contents/src/pages/docs.astro +++ b/packages/astro/test/fixtures/content-collections-same-contents/src/pages/docs.astro @@ -1,7 +1,7 @@ --- -import { getEntryBySlug } from 'astro:content'; -const entry = await getEntryBySlug('docs', 'one'); -const { Content } = await entry.render(); +import { getEntry, render } from 'astro:content'; +const entry = await getEntry('docs', 'one'); +const { Content } = await render(entry); --- diff --git a/packages/astro/test/fixtures/content-collections-with-config-mjs/src/pages/index.astro b/packages/astro/test/fixtures/content-collections-with-config-mjs/src/pages/index.astro index 4152c0734663..39bfb7ed6ca4 100644 --- a/packages/astro/test/fixtures/content-collections-with-config-mjs/src/pages/index.astro +++ b/packages/astro/test/fixtures/content-collections-with-config-mjs/src/pages/index.astro @@ -1,5 +1,5 @@ --- -import {getEntryBySlug} from "astro:content" -const blogEntry = await getEntryBySlug("blog", "introduction"); +import {getEntry} from "astro:content" +const blogEntry = await getEntry("blog", "introduction"); --- {blogEntry.data.title} \ No newline at end of file diff --git a/packages/astro/test/fixtures/content-collections-with-config-mts/src/pages/index.astro b/packages/astro/test/fixtures/content-collections-with-config-mts/src/pages/index.astro index 4152c0734663..39bfb7ed6ca4 100644 --- a/packages/astro/test/fixtures/content-collections-with-config-mts/src/pages/index.astro +++ b/packages/astro/test/fixtures/content-collections-with-config-mts/src/pages/index.astro @@ -1,5 +1,5 @@ --- -import {getEntryBySlug} from "astro:content" -const blogEntry = await getEntryBySlug("blog", "introduction"); +import {getEntry} from "astro:content" +const blogEntry = await getEntry("blog", "introduction"); --- {blogEntry.data.title} \ No newline at end of file diff --git a/packages/astro/test/fixtures/content-collections/src/content.config.ts b/packages/astro/test/fixtures/content-collections/src/content.config.ts index 0c846d2a71ec..6b2a80693ecf 100644 --- a/packages/astro/test/fixtures/content-collections/src/content.config.ts +++ b/packages/astro/test/fixtures/content-collections/src/content.config.ts @@ -1,18 +1,21 @@ import { defineCollection, z } from 'astro:content'; +import { glob } from 'astro/loaders'; const withData = defineCollection({ - type: 'data', + loader: glob({ pattern: '**/*.{json,yaml,yml}', base: './src/content/with-data' }), schema: z.object({ title: z.string(), }), }); const withCustomSlugs = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/with-custom-slugs' }), // Ensure schema passes even when `slug` is present schema: z.object({}).strict(), }); const withSchemaConfig = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/with-schema-config' }), schema: z.object({ title: z.string(), isDraft: z.boolean().default(false), @@ -22,6 +25,7 @@ const withSchemaConfig = defineCollection({ }); const withUnionSchema = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/with-union-schema' }), schema: z.discriminatedUnion('type', [ z.object({ type: z.literal('post'), @@ -36,7 +40,7 @@ const withUnionSchema = defineCollection({ }); const withSymlinkedData = defineCollection({ - type: 'data', + loader: glob({ pattern: '**/*.{json,yaml,yml}', base: './src/content/with-symlinked-data' }), schema: ({ image }) => z.object({ alt: z.string(), @@ -45,14 +49,16 @@ const withSymlinkedData = defineCollection({ }); const withSymlinkedContent = defineCollection({ - type: 'content', + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/with-symlinked-content' }), schema: z.object({ title: z.string(), date: z.date(), }), }); -const withScripts = defineCollection({}); +const withScripts = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/with-scripts' }), +}); export const collections = { 'with-data': withData, diff --git a/packages/astro/test/fixtures/content-collections/src/pages/entries.json.js b/packages/astro/test/fixtures/content-collections/src/pages/entries.json.js index 06484bcb25ed..d2cade9cc070 100644 --- a/packages/astro/test/fixtures/content-collections/src/pages/entries.json.js +++ b/packages/astro/test/fixtures/content-collections/src/pages/entries.json.js @@ -1,13 +1,13 @@ -import { getEntryBySlug } from 'astro:content'; +import { getEntry } from 'astro:content'; import * as devalue from 'devalue'; import { stripRenderFn } from '../utils.js'; export async function GET() { - const oneWithSchemaConfig = stripRenderFn(await getEntryBySlug('with-schema-config', 'one')); + const oneWithSchemaConfig = stripRenderFn(await getEntry('with-schema-config', 'one')); const twoWithSlugConfig = stripRenderFn( - await getEntryBySlug('with-custom-slugs', 'interesting-two') + await getEntry('with-custom-slugs', 'interesting-two') ); - const postWithUnionSchema = stripRenderFn(await getEntryBySlug('with-union-schema', 'post')); + const postWithUnionSchema = stripRenderFn(await getEntry('with-union-schema', 'post')); return new Response( devalue.stringify({ diff --git a/packages/astro/test/fixtures/content-collections/src/pages/with-scripts/[...slug].astro b/packages/astro/test/fixtures/content-collections/src/pages/with-scripts/[...slug].astro index 893cbb9c61ff..e5605b867e62 100644 --- a/packages/astro/test/fixtures/content-collections/src/pages/with-scripts/[...slug].astro +++ b/packages/astro/test/fixtures/content-collections/src/pages/with-scripts/[...slug].astro @@ -1,16 +1,16 @@ --- -import { getCollection } from 'astro:content'; +import { getCollection, render } from 'astro:content'; export async function getStaticPaths() { const blogEntries = await getCollection('with-scripts'); return blogEntries.map(entry => ({ - params: { slug: entry.slug }, props: { entry }, + params: { slug: entry.id }, props: { entry }, })); } const { entry } = Astro.props; -const { Content } = await entry.render(); +const { Content } = await render(entry); const { title } = entry.data; --- diff --git a/packages/astro/test/fixtures/content-ssr-integration/src/content/config.ts b/packages/astro/test/fixtures/content-ssr-integration/src/content.config.ts similarity index 64% rename from packages/astro/test/fixtures/content-ssr-integration/src/content/config.ts rename to packages/astro/test/fixtures/content-ssr-integration/src/content.config.ts index 8d68c0ec3e85..eedbec2cc1f2 100644 --- a/packages/astro/test/fixtures/content-ssr-integration/src/content/config.ts +++ b/packages/astro/test/fixtures/content-ssr-integration/src/content.config.ts @@ -1,6 +1,8 @@ import { defineCollection, z } from 'astro:content'; +import { glob } from 'astro/loaders'; const blog = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }), schema: z.object({ title: z.string(), description: z.string(), @@ -10,4 +12,4 @@ const blog = defineCollection({ }), }); -export const collections = { blog }; +export const collections = { blog }; \ No newline at end of file diff --git a/packages/astro/test/fixtures/content-ssr-integration/src/pages/posts/[...slug].astro b/packages/astro/test/fixtures/content-ssr-integration/src/pages/posts/[...slug].astro index 1cafafcf11b4..5e9b1c82e66f 100644 --- a/packages/astro/test/fixtures/content-ssr-integration/src/pages/posts/[...slug].astro +++ b/packages/astro/test/fixtures/content-ssr-integration/src/pages/posts/[...slug].astro @@ -1,13 +1,13 @@ --- -import { getCollection } from 'astro:content'; +import { getCollection, render } from 'astro:content'; const { slug } = Astro.params; const posts = await getCollection('blog'); -const post = posts.find((post) => post.slug === slug); +const post = posts.find((post) => post.id === slug); if (!post) { throw new Error(`Not found: ${slug}`); } -const { Content } = await post.render(); +const { Content } = await render(post); --- diff --git a/packages/astro/test/fixtures/content-static-paths-integration/src/pages/posts/[...slug].astro b/packages/astro/test/fixtures/content-static-paths-integration/src/pages/posts/[...slug].astro index 7175b61100e5..db05e1d91b56 100644 --- a/packages/astro/test/fixtures/content-static-paths-integration/src/pages/posts/[...slug].astro +++ b/packages/astro/test/fixtures/content-static-paths-integration/src/pages/posts/[...slug].astro @@ -1,16 +1,16 @@ --- -import { getCollection } from 'astro:content'; +import { getCollection, render } from 'astro:content'; export async function getStaticPaths() { const posts = await getCollection('blog'); return posts.map((post) => ({ - params: { slug: post.slug }, + params: { slug: post.id }, props: post, })); } const { data: { title } } = Astro.props; -const { Content } = await Astro.props.render(); +const { Content } = await render(Astro.props); --- diff --git a/packages/astro/test/fixtures/content/src/content/config.ts b/packages/astro/test/fixtures/content/src/content.config.ts similarity index 59% rename from packages/astro/test/fixtures/content/src/content/config.ts rename to packages/astro/test/fixtures/content/src/content.config.ts index fbf0a269703d..850bec0ade94 100644 --- a/packages/astro/test/fixtures/content/src/content/config.ts +++ b/packages/astro/test/fixtures/content/src/content.config.ts @@ -1,10 +1,12 @@ import { defineCollection, z } from 'astro:content'; +import { glob } from 'astro/loaders'; const blog = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }), schema: z.object({ title: z.string(), description: z.string().max(60, 'For SEO purposes, keep descriptions short!'), }), }); -export const collections = { blog }; +export const collections = { blog }; \ No newline at end of file diff --git a/packages/astro/test/fixtures/content/src/pages/launch-week-component-scripts.astro b/packages/astro/test/fixtures/content/src/pages/launch-week-component-scripts.astro index 3936b2f8d082..b8e36d1f52e6 100644 --- a/packages/astro/test/fixtures/content/src/pages/launch-week-component-scripts.astro +++ b/packages/astro/test/fixtures/content/src/pages/launch-week-component-scripts.astro @@ -1,8 +1,8 @@ --- -import { getEntryBySlug } from 'astro:content'; +import { getEntry, render } from 'astro:content'; -const entry = await getEntryBySlug('blog', 'promo/launch-week-component-scripts'); -const { Content } = await entry.render(); +const entry = await getEntry('blog', 'promo/launch-week-component-scripts'); +const { Content } = await render(entry); --- diff --git a/packages/astro/test/fixtures/content/src/pages/launch-week-components-export.astro b/packages/astro/test/fixtures/content/src/pages/launch-week-components-export.astro index 463e6519129c..a77244f79f00 100644 --- a/packages/astro/test/fixtures/content/src/pages/launch-week-components-export.astro +++ b/packages/astro/test/fixtures/content/src/pages/launch-week-components-export.astro @@ -1,8 +1,8 @@ --- -import { getEntryBySlug } from 'astro:content'; +import { getEntry, render } from 'astro:content'; -const entry = await getEntryBySlug('blog', 'promo/launch-week-components-export'); -const { Content } = await entry.render(); +const entry = await getEntry('blog', 'promo/launch-week-components-export'); +const { Content } = await render(entry); --- diff --git a/packages/astro/test/fixtures/content/src/pages/launch-week.astro b/packages/astro/test/fixtures/content/src/pages/launch-week.astro index e7a992e2dfe4..71231592330a 100644 --- a/packages/astro/test/fixtures/content/src/pages/launch-week.astro +++ b/packages/astro/test/fixtures/content/src/pages/launch-week.astro @@ -1,8 +1,9 @@ --- -import { getEntryBySlug } from 'astro:content'; +import { getEntry, render } from 'astro:content'; -const entry = await getEntryBySlug('blog', 'promo/launch-week'); -const { Content } = await entry.render(); +const entry = await getEntry('blog', 'promo/launch-week'); + +const { Content } = await render(entry); --- diff --git a/packages/astro/test/fixtures/content/src/pages/with-layout-prop.astro b/packages/astro/test/fixtures/content/src/pages/with-layout-prop.astro deleted file mode 100644 index 4cbb87624267..000000000000 --- a/packages/astro/test/fixtures/content/src/pages/with-layout-prop.astro +++ /dev/null @@ -1,9 +0,0 @@ ---- -import { getEntryBySlug } from 'astro:content'; -import H3 from '../components/H3.astro'; - -const entry = await getEntryBySlug('blog', 'with-layout-prop'); -const { Content } = await entry.render(); ---- -

H3 directly inserted to the page

- \ No newline at end of file diff --git a/packages/astro/test/fixtures/core-image-base/src/content.config.ts b/packages/astro/test/fixtures/core-image-base/src/content.config.ts index aa35fb4b6980..39428c387e24 100644 --- a/packages/astro/test/fixtures/core-image-base/src/content.config.ts +++ b/packages/astro/test/fixtures/core-image-base/src/content.config.ts @@ -1,6 +1,8 @@ import { defineCollection, z } from "astro:content"; +import { glob } from "astro/loaders"; const blogCollection = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }), schema: ({image}) => z.object({ title: z.string(), image: image(), diff --git a/packages/astro/test/fixtures/core-image-base/src/pages/blog/[...slug].astro b/packages/astro/test/fixtures/core-image-base/src/pages/blog/[...slug].astro index 20b21bbd34eb..45dfb8ab9946 100644 --- a/packages/astro/test/fixtures/core-image-base/src/pages/blog/[...slug].astro +++ b/packages/astro/test/fixtures/core-image-base/src/pages/blog/[...slug].astro @@ -1,16 +1,16 @@ --- import { getImage } from 'astro:assets'; -import { getCollection } from 'astro:content'; +import { getCollection, render } from 'astro:content'; export async function getStaticPaths() { const blogEntries = await getCollection('blog'); return blogEntries.map(entry => ({ - params: { slug: entry.slug }, props: { entry }, + params: { slug: entry.id }, props: { entry }, })); } const { entry } = Astro.props; -const { Content } = await entry.render(); +const { Content } = await render(entry); --- diff --git a/packages/astro/test/fixtures/core-image-deletion/src/content.config.ts b/packages/astro/test/fixtures/core-image-deletion/src/content.config.ts index 1c0eae662372..0e376a0cc885 100644 --- a/packages/astro/test/fixtures/core-image-deletion/src/content.config.ts +++ b/packages/astro/test/fixtures/core-image-deletion/src/content.config.ts @@ -1,7 +1,8 @@ import { defineCollection, z } from 'astro:content'; +import { glob } from 'astro/loaders'; const blog = defineCollection({ - type: 'content', + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }), schema: z.object({ title: z.string(), }) diff --git a/packages/astro/test/fixtures/core-image-deletion/src/pages/blog/[slug].astro b/packages/astro/test/fixtures/core-image-deletion/src/pages/blog/[slug].astro index 63b6eb70e502..cbec825feb45 100644 --- a/packages/astro/test/fixtures/core-image-deletion/src/pages/blog/[slug].astro +++ b/packages/astro/test/fixtures/core-image-deletion/src/pages/blog/[slug].astro @@ -1,12 +1,12 @@ --- -import { getCollection } from "astro:content"; +import { getCollection, render } from "astro:content"; import type { GetStaticPaths } from "astro"; export const getStaticPaths = (async () => { const blog = await getCollection("blog"); return blog.map((post) => ({ params: { - slug: post.slug, + slug: post.id, }, props: { post @@ -16,7 +16,7 @@ export const getStaticPaths = (async () => { const { post } = Astro.props; -const { Content } = await post.render(); +const { Content } = await render(post); --- diff --git a/packages/astro/test/fixtures/core-image-errors/src/content/config.ts b/packages/astro/test/fixtures/core-image-errors/src/content.config.ts similarity index 70% rename from packages/astro/test/fixtures/core-image-errors/src/content/config.ts rename to packages/astro/test/fixtures/core-image-errors/src/content.config.ts index aa35fb4b6980..7f9a62fa8018 100644 --- a/packages/astro/test/fixtures/core-image-errors/src/content/config.ts +++ b/packages/astro/test/fixtures/core-image-errors/src/content.config.ts @@ -1,6 +1,8 @@ import { defineCollection, z } from "astro:content"; +import { glob } from "astro/loaders"; const blogCollection = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }), schema: ({image}) => z.object({ title: z.string(), image: image(), @@ -12,4 +14,4 @@ const blogCollection = defineCollection({ export const collections = { blog: blogCollection -}; +}; \ No newline at end of file diff --git a/packages/astro/test/fixtures/core-image-errors/src/pages/blog/[...slug].astro b/packages/astro/test/fixtures/core-image-errors/src/pages/blog/[...slug].astro index b9e8895ff4bb..49733bd1e3d6 100644 --- a/packages/astro/test/fixtures/core-image-errors/src/pages/blog/[...slug].astro +++ b/packages/astro/test/fixtures/core-image-errors/src/pages/blog/[...slug].astro @@ -1,15 +1,15 @@ --- -import { getCollection } from 'astro:content'; +import { getCollection, render } from 'astro:content'; export async function getStaticPaths() { const blogEntries = await getCollection('blog'); return blogEntries.map(entry => ({ - params: { slug: entry.slug }, props: { entry }, + params: { slug: entry.id }, props: { entry }, })); } const { entry } = Astro.props; -const { Content } = await entry.render(); +const { Content } = await render(entry); --- diff --git a/packages/astro/test/fixtures/core-image-ssg/src/content.config.ts b/packages/astro/test/fixtures/core-image-ssg/src/content.config.ts index aa35fb4b6980..39428c387e24 100644 --- a/packages/astro/test/fixtures/core-image-ssg/src/content.config.ts +++ b/packages/astro/test/fixtures/core-image-ssg/src/content.config.ts @@ -1,6 +1,8 @@ import { defineCollection, z } from "astro:content"; +import { glob } from "astro/loaders"; const blogCollection = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }), schema: ({image}) => z.object({ title: z.string(), image: image(), diff --git a/packages/astro/test/fixtures/core-image-ssg/src/pages/blog/[...slug].astro b/packages/astro/test/fixtures/core-image-ssg/src/pages/blog/[...slug].astro index 1173b0fd1e6e..b40fe4144a3b 100644 --- a/packages/astro/test/fixtures/core-image-ssg/src/pages/blog/[...slug].astro +++ b/packages/astro/test/fixtures/core-image-ssg/src/pages/blog/[...slug].astro @@ -1,15 +1,15 @@ --- -import { getCollection } from 'astro:content'; +import { getCollection, render } from 'astro:content'; export async function getStaticPaths() { const blogEntries = await getCollection('blog'); return blogEntries.map(entry => ({ - params: { slug: entry.slug }, props: { entry }, + params: { slug: entry.id }, props: { entry }, })); } const { entry } = Astro.props; -const { Content } = await entry.render(); +const { Content } = await render(entry); --- diff --git a/packages/astro/test/fixtures/core-image-svg/src/content/config.ts b/packages/astro/test/fixtures/core-image-svg/src/content.config.ts similarity index 59% rename from packages/astro/test/fixtures/core-image-svg/src/content/config.ts rename to packages/astro/test/fixtures/core-image-svg/src/content.config.ts index fbf0a269703d..850bec0ade94 100644 --- a/packages/astro/test/fixtures/core-image-svg/src/content/config.ts +++ b/packages/astro/test/fixtures/core-image-svg/src/content.config.ts @@ -1,10 +1,12 @@ import { defineCollection, z } from 'astro:content'; +import { glob } from 'astro/loaders'; const blog = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }), schema: z.object({ title: z.string(), description: z.string().max(60, 'For SEO purposes, keep descriptions short!'), }), }); -export const collections = { blog }; +export const collections = { blog }; \ No newline at end of file diff --git a/packages/astro/test/fixtures/core-image-svg/src/pages/blog/[...slug].astro b/packages/astro/test/fixtures/core-image-svg/src/pages/blog/[...slug].astro index e1ced40b1348..9320a5ad1ea9 100644 --- a/packages/astro/test/fixtures/core-image-svg/src/pages/blog/[...slug].astro +++ b/packages/astro/test/fixtures/core-image-svg/src/pages/blog/[...slug].astro @@ -1,15 +1,15 @@ --- -import { getCollection } from 'astro:content'; +import { getCollection, render } from 'astro:content'; export async function getStaticPaths() { const blogEntries = await getCollection('blog'); return blogEntries.map(entry => ({ - params: { slug: entry.slug }, props: { entry }, + params: { slug: entry.id }, props: { entry }, })); } const { entry } = Astro.props; -const { Content } = await entry.render(); +const { Content } = await render(entry); --- diff --git a/packages/astro/test/fixtures/core-image/src/content/config.ts b/packages/astro/test/fixtures/core-image/src/content.config.ts similarity index 73% rename from packages/astro/test/fixtures/core-image/src/content/config.ts rename to packages/astro/test/fixtures/core-image/src/content.config.ts index f2699e070867..8852ace386c8 100644 --- a/packages/astro/test/fixtures/core-image/src/content/config.ts +++ b/packages/astro/test/fixtures/core-image/src/content.config.ts @@ -1,6 +1,8 @@ import { defineCollection, z } from "astro:content"; +import { glob } from "astro/loaders"; const blogCollection = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }), schema: ({image}) => z.object({ title: z.string(), image: image(), @@ -14,4 +16,4 @@ const blogCollection = defineCollection({ export const collections = { blog: blogCollection -}; +}; \ No newline at end of file diff --git a/packages/astro/test/fixtures/core-image/src/pages/blog/[...slug].astro b/packages/astro/test/fixtures/core-image/src/pages/blog/[...slug].astro index 36d0d5ac9550..dc03dd559bcf 100644 --- a/packages/astro/test/fixtures/core-image/src/pages/blog/[...slug].astro +++ b/packages/astro/test/fixtures/core-image/src/pages/blog/[...slug].astro @@ -1,16 +1,16 @@ --- import { Image, getImage} from 'astro:assets'; -import { getCollection } from 'astro:content'; +import { getCollection, render } from 'astro:content'; export async function getStaticPaths() { const blogEntries = await getCollection('blog'); return blogEntries.map(entry => ({ - params: { slug: entry.slug }, props: { entry }, + params: { slug: entry.id }, props: { entry }, })); } const { entry } = Astro.props; -const { Content } = await entry.render(); +const { Content } = await render(entry); const myImage = await getImage({src: entry.data.image}); --- diff --git a/packages/astro/test/fixtures/css-inline-stylesheets-2/src/pages/index.astro b/packages/astro/test/fixtures/css-inline-stylesheets-2/src/pages/index.astro index 2aecfb0f2eb7..bc96c02453f3 100644 --- a/packages/astro/test/fixtures/css-inline-stylesheets-2/src/pages/index.astro +++ b/packages/astro/test/fixtures/css-inline-stylesheets-2/src/pages/index.astro @@ -1,9 +1,9 @@ --- -import { getEntryBySlug } from 'astro:content'; +import { getEntry, render } from 'astro:content'; import Button from '../components/Button.astro'; -const entry = await getEntryBySlug('en', 'endeavour'); -const { Content } = await entry.render(); +const entry = await getEntry('en', 'endeavour'); +const { Content } = await render(entry); --- - - -
-
- - diff --git a/packages/astro/test/fixtures/legacy-content-collections/src/pages/propagation.astro b/packages/astro/test/fixtures/legacy-content-collections/src/pages/propagation.astro deleted file mode 100644 index 3775697acd00..000000000000 --- a/packages/astro/test/fixtures/legacy-content-collections/src/pages/propagation.astro +++ /dev/null @@ -1,22 +0,0 @@ ---- -import { getCollection } from "astro:content"; -const posts = await getCollection("with-schema-config"); ---- - - - -
-
Hello World
- Styles? -
- - - - diff --git a/packages/astro/test/fixtures/legacy-content-collections/src/pages/with-scripts/[...slug].astro b/packages/astro/test/fixtures/legacy-content-collections/src/pages/with-scripts/[...slug].astro deleted file mode 100644 index e5605b867e62..000000000000 --- a/packages/astro/test/fixtures/legacy-content-collections/src/pages/with-scripts/[...slug].astro +++ /dev/null @@ -1,21 +0,0 @@ ---- -import { getCollection, render } from 'astro:content'; - -export async function getStaticPaths() { - const blogEntries = await getCollection('with-scripts'); - return blogEntries.map(entry => ({ - params: { slug: entry.id }, props: { entry }, - })); -} - -const { entry } = Astro.props; - -const { Content } = await render(entry); -const { title } = entry.data; ---- - -
-

This is a content collection post

-

{title}

- -
diff --git a/packages/astro/test/fixtures/legacy-content-collections/src/utils.js b/packages/astro/test/fixtures/legacy-content-collections/src/utils.js deleted file mode 100644 index 3a6244327862..000000000000 --- a/packages/astro/test/fixtures/legacy-content-collections/src/utils.js +++ /dev/null @@ -1,8 +0,0 @@ -export function stripRenderFn(entryWithRender) { - const { render, ...entry } = entryWithRender; - return entry; -} - -export function stripAllRenderFn(collection = []) { - return collection.map(stripRenderFn); -} diff --git a/packages/astro/test/fixtures/legacy-content-collections/symlinked-collections/content-collection/first.md b/packages/astro/test/fixtures/legacy-content-collections/symlinked-collections/content-collection/first.md deleted file mode 100644 index 0ecb2d8587b0..000000000000 --- a/packages/astro/test/fixtures/legacy-content-collections/symlinked-collections/content-collection/first.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "First Blog" -date: 2024-04-05 ---- - -First blog content. diff --git a/packages/astro/test/fixtures/legacy-content-collections/symlinked-collections/content-collection/second.md b/packages/astro/test/fixtures/legacy-content-collections/symlinked-collections/content-collection/second.md deleted file mode 100644 index dcded99ccf63..000000000000 --- a/packages/astro/test/fixtures/legacy-content-collections/symlinked-collections/content-collection/second.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "Second Blog" -date: 2024-04-06 ---- - -Second blog content. diff --git a/packages/astro/test/fixtures/legacy-content-collections/symlinked-collections/content-collection/third.md b/packages/astro/test/fixtures/legacy-content-collections/symlinked-collections/content-collection/third.md deleted file mode 100644 index 1adee317378b..000000000000 --- a/packages/astro/test/fixtures/legacy-content-collections/symlinked-collections/content-collection/third.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "Third Blog" -date: 2024-04-07 ---- - -Third blog content. diff --git a/packages/astro/test/fixtures/legacy-content-collections/symlinked-collections/data-collection/welcome.json b/packages/astro/test/fixtures/legacy-content-collections/symlinked-collections/data-collection/welcome.json deleted file mode 100644 index 8ab06ff1f24f..000000000000 --- a/packages/astro/test/fixtures/legacy-content-collections/symlinked-collections/data-collection/welcome.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "alt": "Futuristic landscape with chrome buildings and blue skies", - "src": "../../assets/the-future.jpg" -} diff --git a/packages/astro/test/fixtures/legacy-data-collections/astro.config.mjs b/packages/astro/test/fixtures/legacy-data-collections/astro.config.mjs deleted file mode 100644 index 3f4722ff1bb4..000000000000 --- a/packages/astro/test/fixtures/legacy-data-collections/astro.config.mjs +++ /dev/null @@ -1,9 +0,0 @@ -// @ts-check -import { defineConfig } from 'astro/config'; - -// https://astro.build/config -export default defineConfig({ - legacy: { - collections: true, - }, -}); diff --git a/packages/astro/test/fixtures/legacy-data-collections/package.json b/packages/astro/test/fixtures/legacy-data-collections/package.json deleted file mode 100644 index 48fdc63bed82..000000000000 --- a/packages/astro/test/fixtures/legacy-data-collections/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "@test/legacy-data-collections", - "type": "module", - "version": "0.0.1", - "private": true, - "scripts": { - "dev": "astro dev", - "build": "astro build", - "preview": "astro preview", - "astro": "astro" - }, - "dependencies": { - "astro": "workspace:*" - } -} diff --git a/packages/astro/test/fixtures/legacy-data-collections/src/content.config.ts b/packages/astro/test/fixtures/legacy-data-collections/src/content.config.ts deleted file mode 100644 index 4dcb86d595c5..000000000000 --- a/packages/astro/test/fixtures/legacy-data-collections/src/content.config.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { defineCollection, z } from 'astro:content'; -import { glob } from 'astro/loaders'; - -const docs = defineCollection({ - loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/docs' }), - schema: z.object({ - title: z.string(), - }) -}); - -const i18n = defineCollection({ - loader: glob({ pattern: '**/*.{json,yaml,yml}', base: './src/content/i18n' }), - schema: z.object({ - homepage: z.object({ - greeting: z.string(), - preamble: z.string(), - }) - }), -}); - -export const collections = { docs, i18n }; \ No newline at end of file diff --git a/packages/astro/test/fixtures/legacy-data-collections/src/content/authors-without-config/Ben Holmes.yml b/packages/astro/test/fixtures/legacy-data-collections/src/content/authors-without-config/Ben Holmes.yml deleted file mode 100644 index 54e6743d96cc..000000000000 --- a/packages/astro/test/fixtures/legacy-data-collections/src/content/authors-without-config/Ben Holmes.yml +++ /dev/null @@ -1,2 +0,0 @@ -name: Ben J Holmes -twitter: https://twitter.com/bholmesdev diff --git a/packages/astro/test/fixtures/legacy-data-collections/src/content/authors-without-config/Fred K Schott.yml b/packages/astro/test/fixtures/legacy-data-collections/src/content/authors-without-config/Fred K Schott.yml deleted file mode 100644 index 0b51067d9529..000000000000 --- a/packages/astro/test/fixtures/legacy-data-collections/src/content/authors-without-config/Fred K Schott.yml +++ /dev/null @@ -1,2 +0,0 @@ -name: Fred K Schott -twitter: https://twitter.com/FredKSchott diff --git a/packages/astro/test/fixtures/legacy-data-collections/src/content/authors-without-config/Nate Moore.yml b/packages/astro/test/fixtures/legacy-data-collections/src/content/authors-without-config/Nate Moore.yml deleted file mode 100644 index 953f348a08f8..000000000000 --- a/packages/astro/test/fixtures/legacy-data-collections/src/content/authors-without-config/Nate Moore.yml +++ /dev/null @@ -1,2 +0,0 @@ -name: Nate Something Moore -twitter: https://twitter.com/n_moore diff --git a/packages/astro/test/fixtures/legacy-data-collections/src/content/docs/example.md b/packages/astro/test/fixtures/legacy-data-collections/src/content/docs/example.md deleted file mode 100644 index 356e65f64b6a..000000000000 --- a/packages/astro/test/fixtures/legacy-data-collections/src/content/docs/example.md +++ /dev/null @@ -1,3 +0,0 @@ ---- -title: The future of content ---- diff --git a/packages/astro/test/fixtures/legacy-data-collections/src/content/i18n/en.json b/packages/astro/test/fixtures/legacy-data-collections/src/content/i18n/en.json deleted file mode 100644 index 51d127f4a744..000000000000 --- a/packages/astro/test/fixtures/legacy-data-collections/src/content/i18n/en.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "homepage": { - "greeting": "Hello World!", - "preamble": "Welcome to the future of content." - } -} diff --git a/packages/astro/test/fixtures/legacy-data-collections/src/content/i18n/es.json b/packages/astro/test/fixtures/legacy-data-collections/src/content/i18n/es.json deleted file mode 100644 index bf4c7af0fd05..000000000000 --- a/packages/astro/test/fixtures/legacy-data-collections/src/content/i18n/es.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "homepage": { - "greeting": "ยกHola Mundo!", - "preamble": "Bienvenido al futuro del contenido." - } -} diff --git a/packages/astro/test/fixtures/legacy-data-collections/src/content/i18n/fr.yaml b/packages/astro/test/fixtures/legacy-data-collections/src/content/i18n/fr.yaml deleted file mode 100644 index 90a86d411f6e..000000000000 --- a/packages/astro/test/fixtures/legacy-data-collections/src/content/i18n/fr.yaml +++ /dev/null @@ -1,3 +0,0 @@ -homepage: - greeting: "Bonjour le monde!" - preamble: "Bienvenue dans le futur du contenu." diff --git a/packages/astro/test/fixtures/legacy-data-collections/src/pages/authors/[id].json.js b/packages/astro/test/fixtures/legacy-data-collections/src/pages/authors/[id].json.js deleted file mode 100644 index 8d5365a2eb2d..000000000000 --- a/packages/astro/test/fixtures/legacy-data-collections/src/pages/authors/[id].json.js +++ /dev/null @@ -1,18 +0,0 @@ -import { getEntry } from 'astro:content'; - -const ids = ['Ben Holmes', 'Fred K Schott', 'Nate Moore']; - -export function getStaticPaths() { - return ids.map((id) => ({ params: { id } })); -} - -/** @param {import('astro').APIContext} params */ -export async function GET({ params }) { - const { id } = params; - const author = await getEntry('authors-without-config', id); - if (!author) { - return Response.json({ error: `Author ${id} Not found` }); - } else { - return Response.json(author); - } -} diff --git a/packages/astro/test/fixtures/legacy-data-collections/src/pages/authors/all.json.js b/packages/astro/test/fixtures/legacy-data-collections/src/pages/authors/all.json.js deleted file mode 100644 index 79dd8cd9dd3c..000000000000 --- a/packages/astro/test/fixtures/legacy-data-collections/src/pages/authors/all.json.js +++ /dev/null @@ -1,6 +0,0 @@ -import { getCollection } from 'astro:content'; - -export async function GET() { - const authors = await getCollection('authors-without-config'); - return Response.json(authors); -} diff --git a/packages/astro/test/fixtures/legacy-data-collections/src/pages/translations/[lang].json.js b/packages/astro/test/fixtures/legacy-data-collections/src/pages/translations/[lang].json.js deleted file mode 100644 index c6b0cfff669b..000000000000 --- a/packages/astro/test/fixtures/legacy-data-collections/src/pages/translations/[lang].json.js +++ /dev/null @@ -1,18 +0,0 @@ -import { getEntry } from 'astro:content'; - -const langs = ['en', 'es', 'fr']; - -export function getStaticPaths() { - return langs.map((lang) => ({ params: { lang } })); -} - -/** @param {import('astro').APIContext} params */ -export async function GET({ params }) { - const { lang } = params; - const translations = await getEntry('i18n', lang); - if (!translations) { - return Response.json({ error: `Translation ${lang} Not found` }); - } else { - return Response.json(translations); - } -} diff --git a/packages/astro/test/fixtures/legacy-data-collections/src/pages/translations/all.json.js b/packages/astro/test/fixtures/legacy-data-collections/src/pages/translations/all.json.js deleted file mode 100644 index f1ebb15b761e..000000000000 --- a/packages/astro/test/fixtures/legacy-data-collections/src/pages/translations/all.json.js +++ /dev/null @@ -1,6 +0,0 @@ -import { getCollection } from 'astro:content'; - -export async function GET() { - const translations = await getCollection('i18n'); - return Response.json(translations); -} diff --git a/packages/astro/test/fixtures/legacy-data-collections/src/pages/translations/by-id.json.js b/packages/astro/test/fixtures/legacy-data-collections/src/pages/translations/by-id.json.js deleted file mode 100644 index d11253d8f22c..000000000000 --- a/packages/astro/test/fixtures/legacy-data-collections/src/pages/translations/by-id.json.js +++ /dev/null @@ -1,6 +0,0 @@ -import { getEntry } from 'astro:content'; - -export async function GET() { - const item = await getEntry('i18n', 'en'); - return Response.json(item); -} diff --git a/packages/astro/test/units/content-collections/get-entry-type.test.js b/packages/astro/test/units/content-collections/get-entry-type.test.js index d8dcb459b85c..45d3c57081c9 100644 --- a/packages/astro/test/units/content-collections/get-entry-type.test.js +++ b/packages/astro/test/units/content-collections/get-entry-type.test.js @@ -19,7 +19,7 @@ const fixtures = [ title: 'With underscore levels above the content directory tree', contentPaths: { config: { - url: new URL('_src/content/config.ts', import.meta.url), + url: new URL('_src/content.config.ts', import.meta.url), exists: true, }, contentDir: new URL('_src/content/', import.meta.url), diff --git a/packages/integrations/cloudflare/test/fixtures/compile-image-service/src/content/config.ts b/packages/integrations/cloudflare/test/fixtures/compile-image-service/src/content.config.ts similarity index 100% rename from packages/integrations/cloudflare/test/fixtures/compile-image-service/src/content/config.ts rename to packages/integrations/cloudflare/test/fixtures/compile-image-service/src/content.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/content-collections/src/content/config.ts b/packages/integrations/markdoc/test/fixtures/content-collections/src/content.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/content-collections/src/content/config.ts rename to packages/integrations/markdoc/test/fixtures/content-collections/src/content.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/collection.json.js b/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/collection.json.js index cb3c84652622..595145f38a29 100644 --- a/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/collection.json.js +++ b/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/collection.json.js @@ -1,8 +1,7 @@ import { getCollection } from 'astro:content'; import { stringify } from 'devalue'; -import { stripAllRenderFn } from '../../utils.js'; export async function GET() { const posts = await getCollection('blog'); - return new Response(stringify(stripAllRenderFn(posts))); + return new Response(stringify(posts)); } diff --git a/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/entry.json.js b/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/entry.json.js index 53dd17013ba7..8ddc63348d13 100644 --- a/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/entry.json.js +++ b/packages/integrations/markdoc/test/fixtures/content-collections/src/pages/entry.json.js @@ -1,8 +1,7 @@ -import { getEntryBySlug } from 'astro:content'; +import { getEntry } from 'astro:content'; import { stringify } from 'devalue'; -import { stripRenderFn } from '../../utils.js'; export async function GET() { - const post = await getEntryBySlug('blog', 'post-1'); - return new Response(stringify(stripRenderFn(post))); + const post = await getEntry('blog', 'post-1'); + return new Response(stringify(post)); } diff --git a/packages/integrations/markdoc/test/fixtures/content-collections/utils.js b/packages/integrations/markdoc/test/fixtures/content-collections/utils.js deleted file mode 100644 index 3a6244327862..000000000000 --- a/packages/integrations/markdoc/test/fixtures/content-collections/utils.js +++ /dev/null @@ -1,8 +0,0 @@ -export function stripRenderFn(entryWithRender) { - const { render, ...entry } = entryWithRender; - return entry; -} - -export function stripAllRenderFn(collection = []) { - return collection.map(stripRenderFn); -} diff --git a/packages/integrations/markdoc/test/fixtures/headings-custom/src/content/config.ts b/packages/integrations/markdoc/test/fixtures/headings-custom/src/content.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/headings-custom/src/content/config.ts rename to packages/integrations/markdoc/test/fixtures/headings-custom/src/content.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/headings/src/content/config.ts b/packages/integrations/markdoc/test/fixtures/headings/src/content.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/headings/src/content/config.ts rename to packages/integrations/markdoc/test/fixtures/headings/src/content.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/image-assets-custom/src/content/config.ts b/packages/integrations/markdoc/test/fixtures/image-assets-custom/src/content.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/image-assets-custom/src/content/config.ts rename to packages/integrations/markdoc/test/fixtures/image-assets-custom/src/content.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/image-assets/src/content/config.ts b/packages/integrations/markdoc/test/fixtures/image-assets/src/content.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/image-assets/src/content/config.ts rename to packages/integrations/markdoc/test/fixtures/image-assets/src/content.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/render with-space/src/content/config.ts b/packages/integrations/markdoc/test/fixtures/render with-space/src/content.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/render with-space/src/content/config.ts rename to packages/integrations/markdoc/test/fixtures/render with-space/src/content.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/render-html/src/content/config.ts b/packages/integrations/markdoc/test/fixtures/render-html/src/content.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/render-html/src/content/config.ts rename to packages/integrations/markdoc/test/fixtures/render-html/src/content.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/render-null/src/content/config.ts b/packages/integrations/markdoc/test/fixtures/render-null/src/content.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/render-null/src/content/config.ts rename to packages/integrations/markdoc/test/fixtures/render-null/src/content.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/render-partials/src/content/config.ts b/packages/integrations/markdoc/test/fixtures/render-partials/src/content.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/render-partials/src/content/config.ts rename to packages/integrations/markdoc/test/fixtures/render-partials/src/content.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/render-simple/src/content/config.ts b/packages/integrations/markdoc/test/fixtures/render-simple/src/content.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/render-simple/src/content/config.ts rename to packages/integrations/markdoc/test/fixtures/render-simple/src/content.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/render-typographer/src/content/config.ts b/packages/integrations/markdoc/test/fixtures/render-typographer/src/content.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/render-typographer/src/content/config.ts rename to packages/integrations/markdoc/test/fixtures/render-typographer/src/content.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/render-with-components/src/content/config.ts b/packages/integrations/markdoc/test/fixtures/render-with-components/src/content.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/render-with-components/src/content/config.ts rename to packages/integrations/markdoc/test/fixtures/render-with-components/src/content.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/render-with-config/src/content/config.ts b/packages/integrations/markdoc/test/fixtures/render-with-config/src/content.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/render-with-config/src/content/config.ts rename to packages/integrations/markdoc/test/fixtures/render-with-config/src/content.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/content/config.ts b/packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/content.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/content/config.ts rename to packages/integrations/markdoc/test/fixtures/render-with-extends-components/src/content.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/render-with-indented-components/src/content/config.ts b/packages/integrations/markdoc/test/fixtures/render-with-indented-components/src/content.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/render-with-indented-components/src/content/config.ts rename to packages/integrations/markdoc/test/fixtures/render-with-indented-components/src/content.config.ts diff --git a/packages/integrations/markdoc/test/fixtures/variables/src/content/config.ts b/packages/integrations/markdoc/test/fixtures/variables/src/content.config.ts similarity index 100% rename from packages/integrations/markdoc/test/fixtures/variables/src/content/config.ts rename to packages/integrations/markdoc/test/fixtures/variables/src/content.config.ts diff --git a/packages/integrations/mdx/test/fixtures/css-head-mdx/src/content/config.ts b/packages/integrations/mdx/test/fixtures/css-head-mdx/src/content.config.ts similarity index 100% rename from packages/integrations/mdx/test/fixtures/css-head-mdx/src/content/config.ts rename to packages/integrations/mdx/test/fixtures/css-head-mdx/src/content.config.ts diff --git a/packages/integrations/mdx/test/fixtures/mdx-images/src/content/config.ts b/packages/integrations/mdx/test/fixtures/mdx-images/src/content.config.ts similarity index 100% rename from packages/integrations/mdx/test/fixtures/mdx-images/src/content/config.ts rename to packages/integrations/mdx/test/fixtures/mdx-images/src/content.config.ts diff --git a/packages/integrations/mdx/test/fixtures/mdx-plus-react-errors/src/content/config.js b/packages/integrations/mdx/test/fixtures/mdx-plus-react-errors/src/content.config.js similarity index 100% rename from packages/integrations/mdx/test/fixtures/mdx-plus-react-errors/src/content/config.js rename to packages/integrations/mdx/test/fixtures/mdx-plus-react-errors/src/content.config.js From 2371ef1ace00bfe2f2604b02b8025529855afab8 Mon Sep 17 00:00:00 2001 From: Matt Kane Date: Mon, 22 Sep 2025 16:10:16 +0100 Subject: [PATCH 11/19] Test fixes --- .../astro/test/css-inline-stylesheets.test.js | 5 +- .../fixtures/astro-mode/src/content.config.ts | 50 +++++++++++++++++++ .../src/content.config.ts | 13 +++++ .../src/pages/index.astro | 3 ++ .../src/content.config.ts | 13 +++++ .../src/pages/index.astro | 3 ++ 6 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 packages/astro/test/fixtures/astro-mode/src/content.config.ts create mode 100644 packages/astro/test/fixtures/css-inline-stylesheets-2/src/content.config.ts create mode 100644 packages/astro/test/fixtures/css-inline-stylesheets/src/content.config.ts diff --git a/packages/astro/test/css-inline-stylesheets.test.js b/packages/astro/test/css-inline-stylesheets.test.js index 7bae334e14cc..b4162a7cf4f1 100644 --- a/packages/astro/test/css-inline-stylesheets.test.js +++ b/packages/astro/test/css-inline-stylesheets.test.js @@ -100,7 +100,7 @@ describe('Setting inlineStylesheets to auto in static output', () => { }, vite: { build: { - assetsInlineLimit: 512, + assetsInlineLimit: 2048, }, }, }); @@ -110,11 +110,10 @@ describe('Setting inlineStylesheets to auto in static output', () => { it('Renders some