astro 5.0.0-beta.3 → 5.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client.d.ts +1 -1
- package/dist/actions/runtime/virtual/get-action.js +1 -1
- package/dist/assets/utils/transformToPath.js +5 -1
- package/dist/content/content-layer.js +16 -1
- package/dist/content/data-store.d.ts +2 -0
- package/dist/content/loaders/glob.d.ts +5 -0
- package/dist/content/loaders/glob.js +29 -8
- package/dist/content/mutable-data-store.d.ts +2 -19
- package/dist/content/mutable-data-store.js +14 -1
- package/dist/content/runtime.d.ts +16 -10
- package/dist/content/runtime.js +40 -19
- package/dist/content/types-generator.js +3 -2
- package/dist/content/utils.d.ts +44 -28
- package/dist/content/utils.js +96 -3
- package/dist/content/vite-plugin-content-virtual-mod.js +24 -31
- package/dist/core/app/node.js +2 -1
- package/dist/core/app/types.d.ts +1 -1
- package/dist/core/base-pipeline.d.ts +2 -2
- package/dist/core/base-pipeline.js +4 -1
- package/dist/core/build/generate.js +6 -5
- package/dist/core/build/static-build.js +2 -2
- package/dist/core/config/schema.d.ts +167 -133
- package/dist/core/config/schema.js +6 -2
- package/dist/core/constants.js +1 -1
- package/dist/core/create-vite.js +3 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/dev/restart.js +5 -2
- package/dist/core/errors/dev/utils.js +5 -5
- package/dist/core/errors/errors-data.d.ts +12 -2
- package/dist/core/errors/errors-data.js +7 -1
- package/dist/core/fs/index.d.ts +1 -1
- package/dist/core/fs/index.js +2 -5
- package/dist/core/logger/vite.js +2 -2
- package/dist/core/messages.js +2 -2
- package/dist/core/render/params-and-props.js +1 -1
- package/dist/core/render-context.js +1 -1
- package/dist/runtime/server/astro-island.js +2 -1
- package/dist/runtime/server/astro-island.prebuilt-dev.d.ts +1 -1
- package/dist/runtime/server/astro-island.prebuilt-dev.js +1 -1
- package/dist/runtime/server/astro-island.prebuilt.d.ts +1 -1
- package/dist/runtime/server/astro-island.prebuilt.js +1 -1
- package/dist/runtime/server/endpoint.js +11 -2
- package/dist/runtime/server/render/server-islands.js +2 -2
- package/dist/runtime/server/serialize.js +11 -4
- package/dist/types/public/config.d.ts +44 -2
- package/dist/vite-plugin-astro/index.js +8 -0
- package/dist/vite-plugin-astro-server/response.js +2 -1
- package/dist/vite-plugin-hmr-reload/index.d.ts +7 -0
- package/dist/vite-plugin-hmr-reload/index.js +28 -0
- package/package.json +11 -12
- package/templates/actions.mjs +5 -1
- package/templates/content/module.mjs +8 -6
package/client.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ interface ImportMeta {
|
|
|
19
19
|
* Astro and Vite expose environment variables through `import.meta.env`. For a complete list of the environment variables available, see the two references below.
|
|
20
20
|
*
|
|
21
21
|
* - [Astro reference](https://docs.astro.build/en/guides/environment-variables/#default-environment-variables)
|
|
22
|
-
* - [Vite reference](https://
|
|
22
|
+
* - [Vite reference](https://vite.dev/guide/env-and-mode.html#env-variables)
|
|
23
23
|
*/
|
|
24
24
|
readonly env: ImportMetaEnv;
|
|
25
25
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ActionNotFoundError } from "../../../core/errors/errors-data.js";
|
|
2
2
|
import { AstroError } from "../../../core/errors/errors.js";
|
|
3
3
|
async function getAction(path) {
|
|
4
|
-
const pathKeys = path.replace("/_actions/", "").split(".");
|
|
4
|
+
const pathKeys = path.replace("/_actions/", "").split(".").map((key) => decodeURIComponent(key));
|
|
5
5
|
let { server: actionLookup } = await import("astro:internal-actions");
|
|
6
6
|
if (actionLookup == null || !(typeof actionLookup === "object")) {
|
|
7
7
|
throw new TypeError(
|
|
@@ -6,7 +6,11 @@ import { isESMImportedImage } from "./imageKind.js";
|
|
|
6
6
|
function propsToFilename(filePath, transform, hash) {
|
|
7
7
|
let filename = decodeURIComponent(removeQueryString(filePath));
|
|
8
8
|
const ext = extname(filename);
|
|
9
|
-
|
|
9
|
+
if (filePath.startsWith("data:")) {
|
|
10
|
+
filename = shorthash(filePath);
|
|
11
|
+
} else {
|
|
12
|
+
filename = basename(filename, ext);
|
|
13
|
+
}
|
|
10
14
|
const prefixDirname = isESMImportedImage(transform.src) ? dirname(filePath) : "";
|
|
11
15
|
let outputExt = transform.format ? `.${transform.format}` : ext;
|
|
12
16
|
return decodeURIComponent(`${prefixDirname}/${filename}_${hash}${outputExt}`);
|
|
@@ -107,10 +107,25 @@ class ContentLayer {
|
|
|
107
107
|
logger.info("Syncing content");
|
|
108
108
|
const { digest: currentConfigDigest } = contentConfig.config;
|
|
109
109
|
this.#lastConfigDigest = currentConfigDigest;
|
|
110
|
+
let shouldClear = false;
|
|
110
111
|
const previousConfigDigest = await this.#store.metaStore().get("config-digest");
|
|
112
|
+
const previousAstroVersion = await this.#store.metaStore().get("astro-version");
|
|
111
113
|
if (currentConfigDigest && previousConfigDigest !== currentConfigDigest) {
|
|
112
|
-
logger.info("Content config changed
|
|
114
|
+
logger.info("Content config changed");
|
|
115
|
+
shouldClear = true;
|
|
116
|
+
}
|
|
117
|
+
if (previousAstroVersion !== "5.0.0-beta.4") {
|
|
118
|
+
logger.info("Astro version changed");
|
|
119
|
+
shouldClear = true;
|
|
120
|
+
}
|
|
121
|
+
if (shouldClear) {
|
|
122
|
+
logger.info("Clearing content store");
|
|
113
123
|
this.#store.clearAll();
|
|
124
|
+
}
|
|
125
|
+
if ("5.0.0-beta.4") {
|
|
126
|
+
await this.#store.metaStore().set("astro-version", "5.0.0-beta.4");
|
|
127
|
+
}
|
|
128
|
+
if (currentConfigDigest) {
|
|
114
129
|
await this.#store.metaStore().set("config-digest", currentConfigDigest);
|
|
115
130
|
}
|
|
116
131
|
await Promise.all(
|
|
@@ -31,6 +31,8 @@ export interface DataEntry<TData extends Record<string, unknown> = Record<string
|
|
|
31
31
|
*/
|
|
32
32
|
deferredRender?: boolean;
|
|
33
33
|
assetImports?: Array<string>;
|
|
34
|
+
/** @deprecated */
|
|
35
|
+
legacyId?: string;
|
|
34
36
|
}
|
|
35
37
|
/**
|
|
36
38
|
* A read-only data store for content collections. This is used to retrieve data from the content layer at runtime.
|
|
@@ -23,3 +23,8 @@ export interface GlobOptions {
|
|
|
23
23
|
* @param pattern A glob pattern to match files, relative to the content directory.
|
|
24
24
|
*/
|
|
25
25
|
export declare function glob(globOptions: GlobOptions): Loader;
|
|
26
|
+
/** @private */
|
|
27
|
+
export declare function glob(globOptions: GlobOptions & {
|
|
28
|
+
/** @deprecated */
|
|
29
|
+
_legacy?: true;
|
|
30
|
+
}): Loader;
|
|
@@ -9,7 +9,7 @@ function generateIdDefault({ entry, base, data }) {
|
|
|
9
9
|
if (data.slug) {
|
|
10
10
|
return data.slug;
|
|
11
11
|
}
|
|
12
|
-
const entryURL = new URL(entry, base);
|
|
12
|
+
const entryURL = new URL(encodeURI(entry), base);
|
|
13
13
|
const { slug } = getContentEntryIdAndSlug({
|
|
14
14
|
entry: entryURL,
|
|
15
15
|
contentDir: base,
|
|
@@ -41,17 +41,19 @@ function glob(globOptions) {
|
|
|
41
41
|
load: async ({ config, logger, watcher, parseData, store, generateDigest, entryTypes }) => {
|
|
42
42
|
const renderFunctionByContentType = /* @__PURE__ */ new WeakMap();
|
|
43
43
|
const untouchedEntries = new Set(store.keys());
|
|
44
|
+
const isLegacy = globOptions._legacy;
|
|
45
|
+
const emulateLegacyCollections = !config.legacy.collections;
|
|
44
46
|
async function syncData(entry, base, entryType) {
|
|
45
47
|
if (!entryType) {
|
|
46
48
|
logger.warn(`No entry type found for ${entry}`);
|
|
47
49
|
return;
|
|
48
50
|
}
|
|
49
|
-
const fileUrl = new URL(entry, base);
|
|
51
|
+
const fileUrl = new URL(encodeURI(entry), base);
|
|
50
52
|
const contents = await fs.readFile(fileUrl, "utf-8").catch((err) => {
|
|
51
53
|
logger.error(`Error reading ${entry}: ${err.message}`);
|
|
52
54
|
return;
|
|
53
55
|
});
|
|
54
|
-
if (!contents) {
|
|
56
|
+
if (!contents && contents !== "") {
|
|
55
57
|
logger.warn(`No contents found for ${entry}`);
|
|
56
58
|
return;
|
|
57
59
|
}
|
|
@@ -60,6 +62,16 @@ function glob(globOptions) {
|
|
|
60
62
|
fileUrl
|
|
61
63
|
});
|
|
62
64
|
const id = generateId({ entry, base, data });
|
|
65
|
+
let legacyId;
|
|
66
|
+
if (isLegacy) {
|
|
67
|
+
const entryURL = new URL(encodeURI(entry), base);
|
|
68
|
+
const legacyOptions = getContentEntryIdAndSlug({
|
|
69
|
+
entry: entryURL,
|
|
70
|
+
contentDir: base,
|
|
71
|
+
collection: ""
|
|
72
|
+
});
|
|
73
|
+
legacyId = legacyOptions.id;
|
|
74
|
+
}
|
|
63
75
|
untouchedEntries.delete(id);
|
|
64
76
|
const existingEntry = store.get(id);
|
|
65
77
|
const digest = generateDigest(contents);
|
|
@@ -80,6 +92,11 @@ function glob(globOptions) {
|
|
|
80
92
|
filePath
|
|
81
93
|
});
|
|
82
94
|
if (entryType.getRenderFunction) {
|
|
95
|
+
if (isLegacy && data.layout) {
|
|
96
|
+
logger.error(
|
|
97
|
+
`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.`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
83
100
|
let render = renderFunctionByContentType.get(entryType);
|
|
84
101
|
if (!render) {
|
|
85
102
|
render = await entryType.getRenderFunction(config);
|
|
@@ -104,7 +121,8 @@ function glob(globOptions) {
|
|
|
104
121
|
filePath: relativePath,
|
|
105
122
|
digest,
|
|
106
123
|
rendered,
|
|
107
|
-
assetImports: rendered?.metadata?.imagePaths
|
|
124
|
+
assetImports: rendered?.metadata?.imagePaths,
|
|
125
|
+
legacyId
|
|
108
126
|
});
|
|
109
127
|
} else if ("contentModuleTypes" in entryType) {
|
|
110
128
|
store.set({
|
|
@@ -113,10 +131,11 @@ function glob(globOptions) {
|
|
|
113
131
|
body,
|
|
114
132
|
filePath: relativePath,
|
|
115
133
|
digest,
|
|
116
|
-
deferredRender: true
|
|
134
|
+
deferredRender: true,
|
|
135
|
+
legacyId
|
|
117
136
|
});
|
|
118
137
|
} else {
|
|
119
|
-
store.set({ id, data: parsedData, body, filePath: relativePath, digest });
|
|
138
|
+
store.set({ id, data: parsedData, body, filePath: relativePath, digest, legacyId });
|
|
120
139
|
}
|
|
121
140
|
fileToIdMap.set(filePath, id);
|
|
122
141
|
}
|
|
@@ -154,7 +173,7 @@ function glob(globOptions) {
|
|
|
154
173
|
if (isConfigFile(entry)) {
|
|
155
174
|
return;
|
|
156
175
|
}
|
|
157
|
-
if (isInContentDir(entry)) {
|
|
176
|
+
if (!emulateLegacyCollections && isInContentDir(entry)) {
|
|
158
177
|
skippedFiles.push(entry);
|
|
159
178
|
return;
|
|
160
179
|
}
|
|
@@ -167,7 +186,9 @@ function glob(globOptions) {
|
|
|
167
186
|
const skipCount = skippedFiles.length;
|
|
168
187
|
if (skipCount > 0) {
|
|
169
188
|
const patternList = Array.isArray(globOptions.pattern) ? globOptions.pattern.join(", ") : globOptions.pattern;
|
|
170
|
-
logger.warn(
|
|
189
|
+
logger.warn(
|
|
190
|
+
`The glob() loader cannot be used for files in ${bold("src/content")} when legacy mode is enabled.`
|
|
191
|
+
);
|
|
171
192
|
if (skipCount > 10) {
|
|
172
193
|
logger.warn(
|
|
173
194
|
`Skipped ${green(skippedFiles.length)} files that matched ${green(patternList)}.`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type PathLike } from 'node:fs';
|
|
2
|
-
import { type DataEntry, ImmutableDataStore
|
|
2
|
+
import { type DataEntry, ImmutableDataStore } from './data-store.js';
|
|
3
3
|
/**
|
|
4
4
|
* Extends the DataStore with the ability to change entries and write them to disk.
|
|
5
5
|
* This is kept as a separate class to avoid needing node builtins at runtime, when read-only access is all that is needed.
|
|
@@ -34,24 +34,7 @@ export declare class MutableDataStore extends ImmutableDataStore {
|
|
|
34
34
|
export interface DataStore {
|
|
35
35
|
get: <TData extends Record<string, unknown> = Record<string, unknown>>(key: string) => DataEntry<TData> | undefined;
|
|
36
36
|
entries: () => Array<[id: string, DataEntry]>;
|
|
37
|
-
set: <TData extends Record<string, unknown>>(opts:
|
|
38
|
-
/** The ID of the entry. Must be unique per collection. */
|
|
39
|
-
id: string;
|
|
40
|
-
/** The data to store. */
|
|
41
|
-
data: TData;
|
|
42
|
-
/** The raw body of the content, if applicable. */
|
|
43
|
-
body?: string;
|
|
44
|
-
/** The file path of the content, if applicable. Relative to the site root. */
|
|
45
|
-
filePath?: string;
|
|
46
|
-
/** A content digest, to check if the content has changed. */
|
|
47
|
-
digest?: number | string;
|
|
48
|
-
/** The rendered content, if applicable. */
|
|
49
|
-
rendered?: RenderedContent;
|
|
50
|
-
/**
|
|
51
|
-
* If an entry is a deferred, its rendering phase is delegated to a virtual module during the runtime phase.
|
|
52
|
-
*/
|
|
53
|
-
deferredRender?: boolean;
|
|
54
|
-
}) => boolean;
|
|
37
|
+
set: <TData extends Record<string, unknown>>(opts: DataEntry<TData>) => boolean;
|
|
55
38
|
values: () => Array<DataEntry>;
|
|
56
39
|
keys: () => Array<string>;
|
|
57
40
|
delete: (key: string) => void;
|
|
@@ -159,7 +159,17 @@ ${lines.join(",\n")}]);
|
|
|
159
159
|
entries: () => this.entries(collectionName),
|
|
160
160
|
values: () => this.values(collectionName),
|
|
161
161
|
keys: () => this.keys(collectionName),
|
|
162
|
-
set: ({
|
|
162
|
+
set: ({
|
|
163
|
+
id: key,
|
|
164
|
+
data,
|
|
165
|
+
body,
|
|
166
|
+
filePath,
|
|
167
|
+
deferredRender,
|
|
168
|
+
digest,
|
|
169
|
+
rendered,
|
|
170
|
+
assetImports,
|
|
171
|
+
legacyId
|
|
172
|
+
}) => {
|
|
163
173
|
if (!key) {
|
|
164
174
|
throw new Error(`ID must be a non-empty string`);
|
|
165
175
|
}
|
|
@@ -200,6 +210,9 @@ ${lines.join(",\n")}]);
|
|
|
200
210
|
if (rendered) {
|
|
201
211
|
entry.rendered = rendered;
|
|
202
212
|
}
|
|
213
|
+
if (legacyId) {
|
|
214
|
+
entry.legacyId = legacyId;
|
|
215
|
+
}
|
|
203
216
|
if (deferredRender) {
|
|
204
217
|
entry.deferredRender = deferredRender;
|
|
205
218
|
if (filePath) {
|
|
@@ -18,10 +18,11 @@ export declare function createGetCollection({ contentCollectionToEntryMap, dataC
|
|
|
18
18
|
getRenderEntryImport: GetEntryImport;
|
|
19
19
|
cacheEntriesByCollection: Map<string, any[]>;
|
|
20
20
|
}): (collection: string, filter?: (entry: any) => unknown) => Promise<any[]>;
|
|
21
|
-
export declare function createGetEntryBySlug({ getEntryImport, getRenderEntryImport, collectionNames, }: {
|
|
21
|
+
export declare function createGetEntryBySlug({ getEntryImport, getRenderEntryImport, collectionNames, getEntry, }: {
|
|
22
22
|
getEntryImport: GetEntryImport;
|
|
23
23
|
getRenderEntryImport: GetEntryImport;
|
|
24
24
|
collectionNames: Set<string>;
|
|
25
|
+
getEntry: ReturnType<typeof createGetEntry>;
|
|
25
26
|
}): (collection: string, slug: string) => Promise<{
|
|
26
27
|
id: any;
|
|
27
28
|
slug: any;
|
|
@@ -30,10 +31,11 @@ export declare function createGetEntryBySlug({ getEntryImport, getRenderEntryImp
|
|
|
30
31
|
data: any;
|
|
31
32
|
render(): Promise<RenderResult>;
|
|
32
33
|
} | undefined>;
|
|
33
|
-
export declare function createGetDataEntryById({ getEntryImport, collectionNames, }: {
|
|
34
|
+
export declare function createGetDataEntryById({ getEntryImport, collectionNames, getEntry, }: {
|
|
34
35
|
getEntryImport: GetEntryImport;
|
|
35
36
|
collectionNames: Set<string>;
|
|
36
|
-
|
|
37
|
+
getEntry: ReturnType<typeof createGetEntry>;
|
|
38
|
+
}): (collection: string, id: string) => Promise<ContentEntryResult | {
|
|
37
39
|
id: any;
|
|
38
40
|
collection: any;
|
|
39
41
|
data: any;
|
|
@@ -79,7 +81,11 @@ export declare function renderEntry(entry: DataEntry | {
|
|
|
79
81
|
render: () => Promise<{
|
|
80
82
|
Content: AstroComponentFactory;
|
|
81
83
|
}>;
|
|
82
|
-
}
|
|
84
|
+
} | (DataEntry & {
|
|
85
|
+
render: () => Promise<{
|
|
86
|
+
Content: AstroComponentFactory;
|
|
87
|
+
}>;
|
|
88
|
+
})): Promise<{
|
|
83
89
|
Content: AstroComponentFactory;
|
|
84
90
|
}>;
|
|
85
91
|
export declare function createReference({ lookupMap }: {
|
|
@@ -88,20 +94,20 @@ export declare function createReference({ lookupMap }: {
|
|
|
88
94
|
id: z.ZodString;
|
|
89
95
|
collection: z.ZodString;
|
|
90
96
|
}, "strip", z.ZodTypeAny, {
|
|
91
|
-
id: string;
|
|
92
97
|
collection: string;
|
|
93
|
-
}, {
|
|
94
98
|
id: string;
|
|
99
|
+
}, {
|
|
95
100
|
collection: string;
|
|
101
|
+
id: string;
|
|
96
102
|
}>, z.ZodObject<{
|
|
97
103
|
slug: z.ZodString;
|
|
98
104
|
collection: z.ZodString;
|
|
99
105
|
}, "strip", z.ZodTypeAny, {
|
|
100
|
-
collection: string;
|
|
101
106
|
slug: string;
|
|
102
|
-
}, {
|
|
103
107
|
collection: string;
|
|
108
|
+
}, {
|
|
104
109
|
slug: string;
|
|
110
|
+
collection: string;
|
|
105
111
|
}>]>, {
|
|
106
112
|
id: string;
|
|
107
113
|
collection: string;
|
|
@@ -109,10 +115,10 @@ export declare function createReference({ lookupMap }: {
|
|
|
109
115
|
slug: string;
|
|
110
116
|
collection: string;
|
|
111
117
|
} | undefined, string | {
|
|
112
|
-
id: string;
|
|
113
118
|
collection: string;
|
|
119
|
+
id: string;
|
|
114
120
|
} | {
|
|
115
|
-
collection: string;
|
|
116
121
|
slug: string;
|
|
122
|
+
collection: string;
|
|
117
123
|
}>;
|
|
118
124
|
export {};
|
package/dist/content/runtime.js
CHANGED
|
@@ -71,7 +71,7 @@ function createGetCollection({
|
|
|
71
71
|
if (hasFilter && !filter(entry)) {
|
|
72
72
|
continue;
|
|
73
73
|
}
|
|
74
|
-
result.push(entry);
|
|
74
|
+
result.push(entry.legacyId ? emulateLegacyEntry(entry) : entry);
|
|
75
75
|
}
|
|
76
76
|
return result;
|
|
77
77
|
} else {
|
|
@@ -127,18 +127,25 @@ function createGetCollection({
|
|
|
127
127
|
function createGetEntryBySlug({
|
|
128
128
|
getEntryImport,
|
|
129
129
|
getRenderEntryImport,
|
|
130
|
-
collectionNames
|
|
130
|
+
collectionNames,
|
|
131
|
+
getEntry
|
|
131
132
|
}) {
|
|
132
133
|
return async function getEntryBySlug(collection, slug) {
|
|
133
134
|
const store = await globalDataStore.get();
|
|
134
135
|
if (!collectionNames.has(collection)) {
|
|
135
136
|
if (store.hasCollection(collection)) {
|
|
137
|
+
const entry2 = await getEntry(collection, slug);
|
|
138
|
+
if (entry2 && "slug" in entry2) {
|
|
139
|
+
return entry2;
|
|
140
|
+
}
|
|
136
141
|
throw new AstroError({
|
|
137
142
|
...AstroErrorData.GetEntryDeprecationError,
|
|
138
143
|
message: AstroErrorData.GetEntryDeprecationError.message(collection, "getEntryBySlug")
|
|
139
144
|
});
|
|
140
145
|
}
|
|
141
|
-
console.warn(
|
|
146
|
+
console.warn(
|
|
147
|
+
`The collection ${JSON.stringify(collection)} does not exist. Please ensure it is defined in your content config.`
|
|
148
|
+
);
|
|
142
149
|
return void 0;
|
|
143
150
|
}
|
|
144
151
|
const entryImport = await getEntryImport(collection, slug);
|
|
@@ -162,18 +169,18 @@ function createGetEntryBySlug({
|
|
|
162
169
|
}
|
|
163
170
|
function createGetDataEntryById({
|
|
164
171
|
getEntryImport,
|
|
165
|
-
collectionNames
|
|
172
|
+
collectionNames,
|
|
173
|
+
getEntry
|
|
166
174
|
}) {
|
|
167
175
|
return async function getDataEntryById(collection, id) {
|
|
168
176
|
const store = await globalDataStore.get();
|
|
169
177
|
if (!collectionNames.has(collection)) {
|
|
170
178
|
if (store.hasCollection(collection)) {
|
|
171
|
-
|
|
172
|
-
...AstroErrorData.GetEntryDeprecationError,
|
|
173
|
-
message: AstroErrorData.GetEntryDeprecationError.message(collection, "getDataEntryById")
|
|
174
|
-
});
|
|
179
|
+
return getEntry(collection, id);
|
|
175
180
|
}
|
|
176
|
-
console.warn(
|
|
181
|
+
console.warn(
|
|
182
|
+
`The collection ${JSON.stringify(collection)} does not exist. Please ensure it is defined in your content config.`
|
|
183
|
+
);
|
|
177
184
|
return void 0;
|
|
178
185
|
}
|
|
179
186
|
const lazyImport = await getEntryImport(collection, id);
|
|
@@ -186,6 +193,19 @@ function createGetDataEntryById({
|
|
|
186
193
|
};
|
|
187
194
|
};
|
|
188
195
|
}
|
|
196
|
+
function emulateLegacyEntry(entry) {
|
|
197
|
+
const legacyEntry = {
|
|
198
|
+
...entry,
|
|
199
|
+
id: entry.legacyId,
|
|
200
|
+
slug: entry.id
|
|
201
|
+
};
|
|
202
|
+
delete legacyEntry.legacyId;
|
|
203
|
+
return {
|
|
204
|
+
...legacyEntry,
|
|
205
|
+
// Define separately so the render function isn't included in the object passed to `renderEntry()`
|
|
206
|
+
render: () => renderEntry(legacyEntry)
|
|
207
|
+
};
|
|
208
|
+
}
|
|
189
209
|
function createGetEntry({
|
|
190
210
|
getEntryImport,
|
|
191
211
|
getRenderEntryImport,
|
|
@@ -214,13 +234,18 @@ function createGetEntry({
|
|
|
214
234
|
}
|
|
215
235
|
const { default: imageAssetMap } = await import("astro:asset-imports");
|
|
216
236
|
entry2.data = updateImageReferencesInData(entry2.data, entry2.filePath, imageAssetMap);
|
|
237
|
+
if (entry2.legacyId) {
|
|
238
|
+
return { ...emulateLegacyEntry(entry2), collection };
|
|
239
|
+
}
|
|
217
240
|
return {
|
|
218
241
|
...entry2,
|
|
219
242
|
collection
|
|
220
243
|
};
|
|
221
244
|
}
|
|
222
245
|
if (!collectionNames.has(collection)) {
|
|
223
|
-
console.warn(
|
|
246
|
+
console.warn(
|
|
247
|
+
`The collection ${JSON.stringify(collection)} does not exist. Please ensure it is defined in your content config.`
|
|
248
|
+
);
|
|
224
249
|
return void 0;
|
|
225
250
|
}
|
|
226
251
|
const entryImport = await getEntryImport(collection, lookupId);
|
|
@@ -307,7 +332,10 @@ function updateImageReferencesInData(data, fileName, imageAssetMap) {
|
|
|
307
332
|
});
|
|
308
333
|
}
|
|
309
334
|
async function renderEntry(entry) {
|
|
310
|
-
if (entry
|
|
335
|
+
if (!entry) {
|
|
336
|
+
throw new AstroError(AstroErrorData.RenderUndefinedEntryError);
|
|
337
|
+
}
|
|
338
|
+
if ("render" in entry && !("legacyId" in entry)) {
|
|
311
339
|
return entry.render();
|
|
312
340
|
}
|
|
313
341
|
if (entry.deferredRender) {
|
|
@@ -431,13 +459,6 @@ function createReference({ lookupMap }) {
|
|
|
431
459
|
});
|
|
432
460
|
return;
|
|
433
461
|
}
|
|
434
|
-
if (!lookupMap[collection] && !collectionIsInStore) {
|
|
435
|
-
ctx.addIssue({
|
|
436
|
-
code: ZodIssueCode.custom,
|
|
437
|
-
message: `**${flattenedErrorPath}:** Reference to ${collection} invalid. Collection does not exist or is empty.`
|
|
438
|
-
});
|
|
439
|
-
return;
|
|
440
|
-
}
|
|
441
462
|
return lookup;
|
|
442
463
|
}
|
|
443
464
|
if (collectionIsInStore) {
|
|
@@ -451,7 +472,7 @@ function createReference({ lookupMap }) {
|
|
|
451
472
|
}
|
|
452
473
|
return { id: lookup, collection };
|
|
453
474
|
}
|
|
454
|
-
if (!lookupMap[collection] && store.collections().size
|
|
475
|
+
if (!lookupMap[collection] && store.collections().size <= 1) {
|
|
455
476
|
return { id: lookup, collection };
|
|
456
477
|
}
|
|
457
478
|
const { type, entries } = lookupMap[collection];
|
|
@@ -390,12 +390,13 @@ async function writeContentFiles({
|
|
|
390
390
|
`;
|
|
391
391
|
break;
|
|
392
392
|
case CONTENT_LAYER_TYPE:
|
|
393
|
+
const legacyTypes = collectionConfig?._legacy ? 'render(): Render[".md"];\n slug: string;\n body: string;\n' : "body?: string;\n";
|
|
393
394
|
dataTypesStr += `${collectionKey}: Record<string, {
|
|
394
395
|
id: string;
|
|
395
|
-
collection: ${collectionKey};
|
|
396
|
+
${legacyTypes} collection: ${collectionKey};
|
|
396
397
|
data: ${dataType};
|
|
397
398
|
rendered?: RenderedContent;
|
|
398
|
-
filePath?: string
|
|
399
|
+
filePath?: string;
|
|
399
400
|
}>;
|
|
400
401
|
`;
|
|
401
402
|
break;
|