astro 6.0.0-alpha.4 → 6.0.0-beta.0
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/dist/assets/build/generate.js +1 -1
- package/dist/assets/build/remote.js +1 -1
- package/dist/assets/endpoint/dev.js +44 -16
- package/dist/assets/fonts/config.d.ts +13 -0
- package/dist/assets/fonts/config.js +4 -2
- package/dist/assets/fonts/constants.js +2 -1
- package/dist/assets/fonts/core/resolve-families.js +1 -0
- package/dist/assets/fonts/definitions.d.ts +10 -2
- package/dist/assets/fonts/infra/remote-font-provider-resolver.d.ts +2 -2
- package/dist/assets/fonts/infra/unifont-font-resolver.d.ts +24 -0
- package/dist/assets/fonts/infra/unifont-font-resolver.js +59 -0
- package/dist/assets/fonts/orchestrate.d.ts +6 -4
- package/dist/assets/fonts/orchestrate.js +16 -32
- package/dist/assets/fonts/providers/entrypoints/bunny.d.ts +1 -1
- package/dist/assets/fonts/providers/entrypoints/fontshare.d.ts +1 -1
- package/dist/assets/fonts/providers/entrypoints/fontsource.d.ts +1 -1
- package/dist/assets/fonts/providers/index.d.ts +6 -8
- package/dist/assets/fonts/providers/index.js +10 -14
- package/dist/assets/fonts/types.d.ts +17 -4
- package/dist/assets/fonts/vite-plugin-fonts.js +6 -1
- package/dist/assets/utils/vendor/image-size/detector.d.ts +1 -1
- package/dist/assets/utils/vendor/image-size/detector.js +2 -1
- package/dist/assets/utils/vendor/image-size/types/bmp.js +1 -1
- package/dist/assets/utils/vendor/image-size/types/gif.js +1 -1
- package/dist/assets/utils/vendor/image-size/types/heif.js +51 -29
- package/dist/assets/utils/vendor/image-size/types/icns.js +13 -14
- package/dist/assets/utils/vendor/image-size/types/ico.js +5 -5
- package/dist/assets/utils/vendor/image-size/types/index.d.ts +3 -3
- package/dist/assets/utils/vendor/image-size/types/index.js +4 -0
- package/dist/assets/utils/vendor/image-size/types/interface.d.ts +6 -6
- package/dist/assets/utils/vendor/image-size/types/j2c.js +2 -2
- package/dist/assets/utils/vendor/image-size/types/jp2.js +5 -3
- package/dist/assets/utils/vendor/image-size/types/jpg.js +4 -4
- package/dist/assets/utils/vendor/image-size/types/jxl-stream.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/jxl-stream.js +36 -0
- package/dist/assets/utils/vendor/image-size/types/jxl.d.ts +2 -0
- package/dist/assets/utils/vendor/image-size/types/jxl.js +57 -0
- package/dist/assets/utils/vendor/image-size/types/ktx.js +1 -1
- package/dist/assets/utils/vendor/image-size/types/png.js +1 -1
- package/dist/assets/utils/vendor/image-size/types/pnm.js +5 -7
- package/dist/assets/utils/vendor/image-size/types/psd.js +1 -1
- package/dist/assets/utils/vendor/image-size/types/tiff.js +93 -40
- package/dist/assets/utils/vendor/image-size/types/utils.d.ts +3 -2
- package/dist/assets/utils/vendor/image-size/types/utils.js +24 -22
- package/dist/assets/utils/vendor/image-size/types/webp.js +5 -6
- package/dist/assets/utils/vendor/image-size/utils/bit-reader.d.ts +10 -0
- package/dist/assets/utils/vendor/image-size/utils/bit-reader.js +41 -0
- package/dist/assets/vite-plugin-assets.js +7 -0
- package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
- package/dist/config/entrypoint.d.ts +1 -2
- package/dist/config/entrypoint.js +1 -2
- package/dist/config/index.js +1 -1
- package/dist/content/config.d.ts +25 -9
- package/dist/content/config.js +13 -17
- package/dist/content/content-layer.js +38 -21
- package/dist/content/loaders/glob.d.ts +4 -1
- package/dist/content/loaders/glob.js +36 -8
- package/dist/content/types-generator.js +10 -6
- package/dist/content/utils.d.ts +17 -1
- package/dist/content/utils.js +129 -8
- package/dist/content/vite-plugin-content-assets.d.ts +4 -5
- package/dist/content/vite-plugin-content-assets.js +3 -10
- package/dist/content/vite-plugin-content-imports.js +5 -1
- package/dist/content/vite-plugin-content-virtual-mod.js +10 -2
- package/dist/core/app/app.d.ts +1 -0
- package/dist/core/app/app.js +3 -0
- package/dist/core/app/base.d.ts +12 -0
- package/dist/core/app/base.js +18 -1
- package/dist/core/app/dev/app.d.ts +4 -1
- package/dist/core/app/dev/app.js +24 -3
- package/dist/core/build/app.d.ts +1 -0
- package/dist/core/build/app.js +3 -0
- package/dist/core/build/index.js +1 -1
- package/dist/core/build/plugins/plugin-manifest.d.ts +4 -6
- package/dist/core/build/plugins/plugin-manifest.js +14 -45
- package/dist/core/build/static-build.d.ts +10 -0
- package/dist/core/build/static-build.js +42 -34
- package/dist/core/config/schemas/base.d.ts +19 -2
- package/dist/core/config/schemas/base.js +6 -2
- package/dist/core/config/schemas/relative.d.ts +24 -3
- package/dist/core/config/settings.js +5 -1
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/container.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/messages.js +2 -2
- package/dist/core/preview/index.js +1 -1
- package/dist/core/routing/dev.d.ts +14 -0
- package/dist/core/routing/dev.js +67 -0
- package/dist/core/routing/index.d.ts +0 -1
- package/dist/core/routing/index.js +0 -2
- package/dist/core/routing/manifest/create.js +9 -6
- package/dist/core/sync/index.js +11 -3
- package/dist/prerender/routing.d.ts +1 -1
- package/dist/prerender/routing.js +4 -4
- package/dist/runtime/client/dev-toolbar/apps/audit/rules/perf.js +1 -0
- package/dist/runtime/server/jsx.js +18 -4
- package/dist/runtime/server/render/astro/render.js +26 -3
- package/dist/runtime/server/render/common.d.ts +1 -0
- package/dist/runtime/server/render/common.js +16 -0
- package/dist/runtime/server/render/component.js +28 -4
- package/dist/runtime/server/render/instruction.d.ts +6 -1
- package/dist/runtime/server/render/script.d.ts +5 -1
- package/dist/runtime/server/render/script.js +7 -10
- package/dist/runtime/server/render/slot.d.ts +5 -0
- package/dist/runtime/server/render/slot.js +9 -4
- package/dist/transitions/router.js +2 -0
- package/dist/types/public/config.d.ts +21 -3
- package/dist/types/public/context.d.ts +307 -291
- package/dist/vite-plugin-app/app.d.ts +3 -0
- package/dist/vite-plugin-app/app.js +30 -80
- package/dist/vite-plugin-app/pipeline.d.ts +0 -1
- package/dist/vite-plugin-app/pipeline.js +3 -12
- package/dist/vite-plugin-astro-server/base.js +3 -2
- package/dist/vite-plugin-astro-server/response.js +4 -6
- package/dist/vite-plugin-config-alias/index.js +3 -2
- package/dist/vite-plugin-pages/pages.js +17 -1
- package/dist/vite-plugin-routes/index.js +1 -1
- package/package.json +13 -13
- package/dist/assets/fonts/core/dedupe-font-faces.d.ts +0 -2
- package/dist/assets/fonts/core/dedupe-font-faces.js +0 -30
- package/dist/assets/fonts/core/extract-unifont-providers.d.ts +0 -10
- package/dist/assets/fonts/core/extract-unifont-providers.js +0 -28
|
@@ -1,44 +1,45 @@
|
|
|
1
1
|
const decoder = new TextDecoder();
|
|
2
2
|
const toUTF8String = (input, start = 0, end = input.length) => decoder.decode(input.slice(start, end));
|
|
3
|
-
const toHexString = (input, start = 0, end = input.length) => input.slice(start, end).reduce((memo, i) => memo +
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
const toHexString = (input, start = 0, end = input.length) => input.slice(start, end).reduce((memo, i) => memo + `0${i.toString(16)}`.slice(-2), "");
|
|
4
|
+
const getView = (input, offset) => new DataView(input.buffer, input.byteOffset + offset);
|
|
5
|
+
const readInt16LE = (input, offset = 0) => getView(input, offset).getInt16(0, true);
|
|
6
|
+
const readUInt16BE = (input, offset = 0) => getView(input, offset).getUint16(0, false);
|
|
7
|
+
const readUInt16LE = (input, offset = 0) => getView(input, offset).getUint16(0, true);
|
|
8
|
+
const readUInt24LE = (input, offset = 0) => {
|
|
9
|
+
const view = getView(input, offset);
|
|
10
|
+
return view.getUint16(0, true) + (view.getUint8(2) << 16);
|
|
7
11
|
};
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const readUInt32BE = (input, offset = 0) => input[offset] * 2 ** 24 + input[offset + 1] * 2 ** 16 + input[offset + 2] * 2 ** 8 + input[offset + 3];
|
|
13
|
-
const readUInt32LE = (input, offset = 0) => input[offset] + input[offset + 1] * 2 ** 8 + input[offset + 2] * 2 ** 16 + input[offset + 3] * 2 ** 24;
|
|
12
|
+
const readInt32LE = (input, offset = 0) => getView(input, offset).getInt32(0, true);
|
|
13
|
+
const readUInt32BE = (input, offset = 0) => getView(input, offset).getUint32(0, false);
|
|
14
|
+
const readUInt32LE = (input, offset = 0) => getView(input, offset).getUint32(0, true);
|
|
15
|
+
const readUInt64 = (input, offset, isBigEndian) => getView(input, offset).getBigUint64(0, !isBigEndian);
|
|
14
16
|
const methods = {
|
|
15
17
|
readUInt16BE,
|
|
16
18
|
readUInt16LE,
|
|
17
19
|
readUInt32BE,
|
|
18
20
|
readUInt32LE
|
|
19
21
|
};
|
|
20
|
-
function readUInt(input, bits, offset, isBigEndian) {
|
|
21
|
-
offset = offset || 0;
|
|
22
|
+
function readUInt(input, bits, offset = 0, isBigEndian = false) {
|
|
22
23
|
const endian = isBigEndian ? "BE" : "LE";
|
|
23
|
-
const methodName =
|
|
24
|
+
const methodName = `readUInt${bits}${endian}`;
|
|
24
25
|
return methods[methodName](input, offset);
|
|
25
26
|
}
|
|
26
|
-
function readBox(
|
|
27
|
-
if (
|
|
28
|
-
const boxSize = readUInt32BE(
|
|
29
|
-
if (
|
|
27
|
+
function readBox(input, offset) {
|
|
28
|
+
if (input.length - offset < 4) return;
|
|
29
|
+
const boxSize = readUInt32BE(input, offset);
|
|
30
|
+
if (input.length - offset < boxSize) return;
|
|
30
31
|
return {
|
|
31
|
-
name: toUTF8String(
|
|
32
|
+
name: toUTF8String(input, 4 + offset, 8 + offset),
|
|
32
33
|
offset,
|
|
33
34
|
size: boxSize
|
|
34
35
|
};
|
|
35
36
|
}
|
|
36
|
-
function findBox(
|
|
37
|
-
while (
|
|
38
|
-
const box = readBox(
|
|
37
|
+
function findBox(input, boxName, currentOffset) {
|
|
38
|
+
while (currentOffset < input.length) {
|
|
39
|
+
const box = readBox(input, currentOffset);
|
|
39
40
|
if (!box) break;
|
|
40
41
|
if (box.name === boxName) return box;
|
|
41
|
-
|
|
42
|
+
currentOffset += box.size > 0 ? box.size : 8;
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
export {
|
|
@@ -51,6 +52,7 @@ export {
|
|
|
51
52
|
readUInt24LE,
|
|
52
53
|
readUInt32BE,
|
|
53
54
|
readUInt32LE,
|
|
55
|
+
readUInt64,
|
|
54
56
|
toHexString,
|
|
55
57
|
toUTF8String
|
|
56
58
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { readInt16LE, readUInt24LE, toHexString, toUTF8String } from "./utils.js";
|
|
2
2
|
function calculateExtended(input) {
|
|
3
3
|
return {
|
|
4
4
|
height: 1 + readUInt24LE(input, 7),
|
|
@@ -24,18 +24,17 @@ const WEBP = {
|
|
|
24
24
|
const vp8Header = "VP8" === toUTF8String(input, 12, 15);
|
|
25
25
|
return riffHeader && webpHeader && vp8Header;
|
|
26
26
|
},
|
|
27
|
-
calculate(
|
|
28
|
-
const chunkHeader = toUTF8String(
|
|
29
|
-
input =
|
|
27
|
+
calculate(_input) {
|
|
28
|
+
const chunkHeader = toUTF8String(_input, 12, 16);
|
|
29
|
+
const input = _input.slice(20, 30);
|
|
30
30
|
if (chunkHeader === "VP8X") {
|
|
31
31
|
const extendedHeader = input[0];
|
|
32
32
|
const validStart = (extendedHeader & 192) === 0;
|
|
33
33
|
const validEnd = (extendedHeader & 1) === 0;
|
|
34
34
|
if (validStart && validEnd) {
|
|
35
35
|
return calculateExtended(input);
|
|
36
|
-
} else {
|
|
37
|
-
throw new TypeError("Invalid WebP");
|
|
38
36
|
}
|
|
37
|
+
throw new TypeError("Invalid WebP");
|
|
39
38
|
}
|
|
40
39
|
if (chunkHeader === "VP8 " && input[0] !== 47) {
|
|
41
40
|
return calculateLossy(input);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** This class helps read Uint8Array bit-by-bit */
|
|
2
|
+
export declare class BitReader {
|
|
3
|
+
private readonly input;
|
|
4
|
+
private readonly endianness;
|
|
5
|
+
private byteOffset;
|
|
6
|
+
private bitOffset;
|
|
7
|
+
constructor(input: Uint8Array, endianness: 'big-endian' | 'little-endian');
|
|
8
|
+
/** Reads a specified number of bits, and move the offset */
|
|
9
|
+
getBits(length?: number): number;
|
|
10
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
class BitReader {
|
|
2
|
+
constructor(input, endianness) {
|
|
3
|
+
this.input = input;
|
|
4
|
+
this.endianness = endianness;
|
|
5
|
+
}
|
|
6
|
+
// Skip the first 16 bits (2 bytes) of signature
|
|
7
|
+
byteOffset = 2;
|
|
8
|
+
bitOffset = 0;
|
|
9
|
+
/** Reads a specified number of bits, and move the offset */
|
|
10
|
+
getBits(length = 1) {
|
|
11
|
+
let result = 0;
|
|
12
|
+
let bitsRead = 0;
|
|
13
|
+
while (bitsRead < length) {
|
|
14
|
+
if (this.byteOffset >= this.input.length) {
|
|
15
|
+
throw new Error("Reached end of input");
|
|
16
|
+
}
|
|
17
|
+
const currentByte = this.input[this.byteOffset];
|
|
18
|
+
const bitsLeft = 8 - this.bitOffset;
|
|
19
|
+
const bitsToRead = Math.min(length - bitsRead, bitsLeft);
|
|
20
|
+
if (this.endianness === "little-endian") {
|
|
21
|
+
const mask = (1 << bitsToRead) - 1;
|
|
22
|
+
const bits = currentByte >> this.bitOffset & mask;
|
|
23
|
+
result |= bits << bitsRead;
|
|
24
|
+
} else {
|
|
25
|
+
const mask = (1 << bitsToRead) - 1 << 8 - this.bitOffset - bitsToRead;
|
|
26
|
+
const bits = (currentByte & mask) >> 8 - this.bitOffset - bitsToRead;
|
|
27
|
+
result = result << bitsToRead | bits;
|
|
28
|
+
}
|
|
29
|
+
bitsRead += bitsToRead;
|
|
30
|
+
this.bitOffset += bitsToRead;
|
|
31
|
+
if (this.bitOffset === 8) {
|
|
32
|
+
this.byteOffset++;
|
|
33
|
+
this.bitOffset = 0;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return result;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
BitReader
|
|
41
|
+
};
|
|
@@ -121,6 +121,13 @@ function assets({ fs, settings, sync, logger }) {
|
|
|
121
121
|
export { default as Font } from "astro/components/Font.astro";
|
|
122
122
|
import * as fontsMod from 'virtual:astro:assets/fonts/internal';
|
|
123
123
|
import { createGetFontData } from "astro/assets/fonts/runtime";
|
|
124
|
+
|
|
125
|
+
export const viteFSConfig = ${JSON.stringify(resolvedConfig.server.fs)} ?? {};
|
|
126
|
+
|
|
127
|
+
export const safeModulePaths = new Set(${JSON.stringify(
|
|
128
|
+
// @ts-expect-error safeModulePaths is internal to Vite
|
|
129
|
+
Array.from(resolvedConfig.safeModulePaths)
|
|
130
|
+
)} ?? []);
|
|
124
131
|
|
|
125
132
|
const assetQueryParams = ${settings.adapter?.client?.assetQueryParams ? `new URLSearchParams(${JSON.stringify(
|
|
126
133
|
Array.from(settings.adapter.client.assetQueryParams.entries())
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { SharpImageServiceConfig } from '../assets/services/sharp.js';
|
|
2
2
|
import type { ImageServiceConfig } from '../types/public/index.js';
|
|
3
|
-
export {
|
|
4
|
-
export type { AstroFontProvider } from '../assets/fonts/types.js';
|
|
3
|
+
export { fontProviders } from '../assets/fonts/providers/index.js';
|
|
5
4
|
export { mergeConfig } from '../core/config/merge.js';
|
|
6
5
|
export { validateConfig } from '../core/config/validate.js';
|
|
7
6
|
export { envField } from '../env/config.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fontProviders } from "../assets/fonts/providers/index.js";
|
|
2
2
|
import { mergeConfig } from "../core/config/merge.js";
|
|
3
3
|
import { validateConfig } from "../core/config/validate.js";
|
|
4
4
|
import { envField } from "../env/config.js";
|
|
@@ -17,7 +17,6 @@ function passthroughImageService() {
|
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
19
|
export {
|
|
20
|
-
defineAstroFontProvider,
|
|
21
20
|
defineConfig,
|
|
22
21
|
envField,
|
|
23
22
|
fontProviders,
|
package/dist/config/index.js
CHANGED
package/dist/content/config.d.ts
CHANGED
|
@@ -43,11 +43,6 @@ export type { ImageFunction };
|
|
|
43
43
|
export type SchemaContext = {
|
|
44
44
|
image: ImageFunction;
|
|
45
45
|
};
|
|
46
|
-
export type LiveCollectionConfig<L extends LiveLoader, S extends BaseSchema | undefined = undefined> = {
|
|
47
|
-
type?: 'live';
|
|
48
|
-
schema?: S;
|
|
49
|
-
loader: L;
|
|
50
|
-
};
|
|
51
46
|
type LoaderConstraint<TData extends {
|
|
52
47
|
id: string;
|
|
53
48
|
}> = Loader | (() => Array<TData> | Promise<Array<TData>> | Record<string, Omit<TData, 'id'> & {
|
|
@@ -55,14 +50,35 @@ type LoaderConstraint<TData extends {
|
|
|
55
50
|
}> | Promise<Record<string, Omit<TData, 'id'> & {
|
|
56
51
|
id?: string;
|
|
57
52
|
}>>);
|
|
58
|
-
|
|
53
|
+
type ContentLayerConfig<S extends BaseSchema, TLoader extends LoaderConstraint<{
|
|
59
54
|
id: string;
|
|
60
55
|
}>> = {
|
|
61
56
|
type?: 'content_layer';
|
|
62
|
-
schema?:
|
|
57
|
+
schema?: S | ((context: SchemaContext) => S);
|
|
63
58
|
loader: TLoader;
|
|
64
59
|
};
|
|
60
|
+
type DataCollectionConfig<S extends BaseSchema> = {
|
|
61
|
+
type: 'data';
|
|
62
|
+
schema?: S | ((context: SchemaContext) => S);
|
|
63
|
+
};
|
|
64
|
+
type ContentCollectionConfig<S extends BaseSchema> = {
|
|
65
|
+
type?: 'content';
|
|
66
|
+
schema?: S | ((context: SchemaContext) => S);
|
|
67
|
+
loader?: never;
|
|
68
|
+
};
|
|
69
|
+
export type LiveCollectionConfig<L extends LiveLoader, S extends BaseSchema | undefined = undefined> = {
|
|
70
|
+
type?: 'live';
|
|
71
|
+
schema?: S;
|
|
72
|
+
loader: L;
|
|
73
|
+
};
|
|
74
|
+
export type CollectionConfig<S extends BaseSchema, TLoader extends LoaderConstraint<{
|
|
75
|
+
id: string;
|
|
76
|
+
}> = LoaderConstraint<{
|
|
77
|
+
id: string;
|
|
78
|
+
}>> = ContentCollectionConfig<S> | DataCollectionConfig<S> | ContentLayerConfig<S, TLoader>;
|
|
65
79
|
export declare function defineLiveCollection<L extends LiveLoader, S extends BaseSchema | undefined = undefined>(config: LiveCollectionConfig<L, S>): LiveCollectionConfig<L, S>;
|
|
66
|
-
export declare function defineCollection<
|
|
80
|
+
export declare function defineCollection<S extends BaseSchema, TLoader extends LoaderConstraint<{
|
|
81
|
+
id: string;
|
|
82
|
+
}> = LoaderConstraint<{
|
|
67
83
|
id: string;
|
|
68
|
-
}>>(config: CollectionConfig<
|
|
84
|
+
}>>(config: CollectionConfig<S, TLoader>): CollectionConfig<S, TLoader>;
|
package/dist/content/config.js
CHANGED
|
@@ -71,24 +71,20 @@ function defineCollection(config) {
|
|
|
71
71
|
)
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
|
-
if (
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (typeof config.loader === "object" && typeof config.loader.load !== "function" && ("loadEntry" in config.loader || "loadCollection" in config.loader)) {
|
|
87
|
-
throw new AstroUserError(
|
|
88
|
-
`Live content collections must be defined in "src/live.config.ts" file. Check your collection definitions in "${importerFilename ?? "your content config file"}" to ensure you are not using a live loader.`
|
|
89
|
-
);
|
|
74
|
+
if ("loader" in config) {
|
|
75
|
+
if (config.type && config.type !== CONTENT_LAYER_TYPE) {
|
|
76
|
+
throw new AstroUserError(
|
|
77
|
+
`A content collection is defined with legacy features (e.g. missing a \`loader\` or has a \`type\`). Check your collection definitions in ${importerFilename ?? "your content config file"} to ensure that all collections are defined using the current properties.`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
if (typeof config.loader === "object" && typeof config.loader.load !== "function" && ("loadEntry" in config.loader || "loadCollection" in config.loader)) {
|
|
81
|
+
throw new AstroUserError(
|
|
82
|
+
`Live content collections must be defined in "src/live.config.ts" file. Check the loaders used in "${importerFilename ?? "your content config file"}" to ensure you are not using a live loader to define a build-time content collection.`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
config.type = CONTENT_LAYER_TYPE;
|
|
90
86
|
}
|
|
91
|
-
config.type =
|
|
87
|
+
if (!config.type) config.type = "content";
|
|
92
88
|
return config;
|
|
93
89
|
}
|
|
94
90
|
export {
|
|
@@ -133,14 +133,24 @@ class ContentLayer {
|
|
|
133
133
|
)
|
|
134
134
|
]);
|
|
135
135
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
136
|
+
switch (contentConfig?.status) {
|
|
137
|
+
case "loaded":
|
|
138
|
+
break;
|
|
139
|
+
case "error":
|
|
140
|
+
logger.error(
|
|
141
|
+
`Error loading content config. Skipping sync.
|
|
142
|
+
${contentConfig.error.message}`
|
|
143
|
+
);
|
|
144
|
+
return;
|
|
145
|
+
case "does-not-exist":
|
|
146
|
+
return;
|
|
147
|
+
case "init":
|
|
148
|
+
case "loading":
|
|
149
|
+
case void 0:
|
|
150
|
+
logger.error(
|
|
151
|
+
`Content config not loaded, skipping sync. Status was ${contentConfig?.status}`
|
|
152
|
+
);
|
|
153
|
+
return;
|
|
144
154
|
}
|
|
145
155
|
logger.info("Syncing content");
|
|
146
156
|
const {
|
|
@@ -164,7 +174,7 @@ ${contentConfig.error.message}`);
|
|
|
164
174
|
logger.info("Content config changed");
|
|
165
175
|
shouldClear = true;
|
|
166
176
|
}
|
|
167
|
-
if (previousAstroVersion && previousAstroVersion !== "6.0.0-
|
|
177
|
+
if (previousAstroVersion && previousAstroVersion !== "6.0.0-beta.0") {
|
|
168
178
|
logger.info("Astro version changed");
|
|
169
179
|
shouldClear = true;
|
|
170
180
|
}
|
|
@@ -172,8 +182,8 @@ ${contentConfig.error.message}`);
|
|
|
172
182
|
logger.info("Clearing content store");
|
|
173
183
|
this.#store.clearAll();
|
|
174
184
|
}
|
|
175
|
-
if ("6.0.0-
|
|
176
|
-
await this.#store.metaStore().set("astro-version", "6.0.0-
|
|
185
|
+
if ("6.0.0-beta.0") {
|
|
186
|
+
await this.#store.metaStore().set("astro-version", "6.0.0-beta.0");
|
|
177
187
|
}
|
|
178
188
|
if (currentConfigDigest) {
|
|
179
189
|
await this.#store.metaStore().set("content-config-digest", currentConfigDigest);
|
|
@@ -184,19 +194,24 @@ ${contentConfig.error.message}`);
|
|
|
184
194
|
if (!options?.loaders?.length) {
|
|
185
195
|
this.#watcher?.removeAllTrackedListeners();
|
|
186
196
|
}
|
|
197
|
+
const backwardsCompatEnabled = this.#settings.config.legacy?.collectionsBackwardsCompat ?? false;
|
|
187
198
|
await Promise.all(
|
|
188
199
|
Object.entries(contentConfig.config.collections).map(async ([name, collection]) => {
|
|
189
|
-
if (collection.type !== CONTENT_LAYER_TYPE) {
|
|
200
|
+
if (collection.type !== CONTENT_LAYER_TYPE && !backwardsCompatEnabled) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (collection.type !== CONTENT_LAYER_TYPE && !("loader" in collection)) {
|
|
190
204
|
return;
|
|
191
205
|
}
|
|
192
206
|
let { schema } = collection;
|
|
193
|
-
|
|
207
|
+
const loaderName = "loader" in collection ? collection.loader.name : "content";
|
|
208
|
+
if (!schema && "loader" in collection && typeof collection.loader === "object") {
|
|
194
209
|
schema = collection.loader.schema;
|
|
195
210
|
if (!schema && collection.loader.createSchema) {
|
|
196
211
|
({ schema } = await collection.loader.createSchema());
|
|
197
212
|
}
|
|
198
213
|
}
|
|
199
|
-
if (options?.loaders && (typeof collection.loader !== "object" || !options.loaders.includes(collection.loader.name))) {
|
|
214
|
+
if (options?.loaders && "loader" in collection && (typeof collection.loader !== "object" || !options.loaders.includes(collection.loader.name))) {
|
|
200
215
|
return;
|
|
201
216
|
}
|
|
202
217
|
const context = await this.#getLoaderContext({
|
|
@@ -214,16 +229,18 @@ ${contentConfig.error.message}`);
|
|
|
214
229
|
{ ...collection, schema },
|
|
215
230
|
false
|
|
216
231
|
),
|
|
217
|
-
loaderName
|
|
232
|
+
loaderName,
|
|
218
233
|
refreshContextData: options?.context
|
|
219
234
|
});
|
|
220
|
-
if (
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
235
|
+
if ("loader" in collection) {
|
|
236
|
+
if (typeof collection.loader === "function") {
|
|
237
|
+
return simpleLoader(collection.loader, context);
|
|
238
|
+
}
|
|
239
|
+
if (!collection.loader?.load) {
|
|
240
|
+
throw new Error(`Collection loader for ${name} does not have a load method`);
|
|
241
|
+
}
|
|
242
|
+
return collection.loader.load(context);
|
|
225
243
|
}
|
|
226
|
-
return collection.loader.load(context);
|
|
227
244
|
})
|
|
228
245
|
);
|
|
229
246
|
await fs.mkdir(this.#settings.config.cacheDir, { recursive: true });
|
|
@@ -18,9 +18,12 @@ interface GlobOptions {
|
|
|
18
18
|
**/
|
|
19
19
|
generateId?: (options: GenerateIdOptions) => string;
|
|
20
20
|
}
|
|
21
|
+
export declare const secretLegacyFlag: unique symbol;
|
|
21
22
|
/**
|
|
22
23
|
* Loads multiple entries, using a glob pattern to match files.
|
|
23
24
|
* @param pattern A glob pattern to match files, relative to the content directory.
|
|
24
25
|
*/
|
|
25
|
-
export declare function glob(globOptions: GlobOptions
|
|
26
|
+
export declare function glob(globOptions: GlobOptions & {
|
|
27
|
+
[secretLegacyFlag]?: boolean;
|
|
28
|
+
}): Loader;
|
|
26
29
|
export {};
|
|
@@ -6,11 +6,19 @@ import colors from "piccolore";
|
|
|
6
6
|
import picomatch from "picomatch";
|
|
7
7
|
import { glob as tinyglobby } from "tinyglobby";
|
|
8
8
|
import { getContentEntryIdAndSlug, posixRelative } from "../utils.js";
|
|
9
|
-
function generateIdDefault({ entry, base, data }) {
|
|
9
|
+
function generateIdDefault({ entry, base, data }, isLegacy) {
|
|
10
10
|
if (data.slug) {
|
|
11
11
|
return data.slug;
|
|
12
12
|
}
|
|
13
13
|
const entryURL = new URL(encodeURI(entry), base);
|
|
14
|
+
if (isLegacy) {
|
|
15
|
+
const { id } = getContentEntryIdAndSlug({
|
|
16
|
+
entry: entryURL,
|
|
17
|
+
contentDir: base,
|
|
18
|
+
collection: ""
|
|
19
|
+
});
|
|
20
|
+
return id;
|
|
21
|
+
}
|
|
14
22
|
const { slug } = getContentEntryIdAndSlug({
|
|
15
23
|
entry: entryURL,
|
|
16
24
|
contentDir: base,
|
|
@@ -24,6 +32,7 @@ function checkPrefix(pattern, prefix) {
|
|
|
24
32
|
}
|
|
25
33
|
return pattern.startsWith(prefix);
|
|
26
34
|
}
|
|
35
|
+
const secretLegacyFlag = Symbol("astro.legacy-glob");
|
|
27
36
|
function glob(globOptions) {
|
|
28
37
|
if (checkPrefix(globOptions.pattern, "../")) {
|
|
29
38
|
throw new Error(
|
|
@@ -35,11 +44,21 @@ function glob(globOptions) {
|
|
|
35
44
|
"Glob patterns cannot start with `/`. Set the `base` option to a parent directory or use a relative path instead."
|
|
36
45
|
);
|
|
37
46
|
}
|
|
38
|
-
const
|
|
47
|
+
const isLegacy = !!globOptions[secretLegacyFlag];
|
|
48
|
+
const generateId = globOptions?.generateId ?? ((opts) => generateIdDefault(opts, isLegacy));
|
|
39
49
|
const fileToIdMap = /* @__PURE__ */ new Map();
|
|
40
50
|
return {
|
|
41
51
|
name: "glob-loader",
|
|
42
|
-
load: async ({
|
|
52
|
+
load: async ({
|
|
53
|
+
config,
|
|
54
|
+
collection,
|
|
55
|
+
logger,
|
|
56
|
+
watcher,
|
|
57
|
+
parseData,
|
|
58
|
+
store,
|
|
59
|
+
generateDigest,
|
|
60
|
+
entryTypes
|
|
61
|
+
}) => {
|
|
43
62
|
const renderFunctionByContentType = /* @__PURE__ */ new WeakMap();
|
|
44
63
|
const untouchedEntries = new Set(store.keys());
|
|
45
64
|
async function syncData(entry, base, entryType, oldId) {
|
|
@@ -84,13 +103,16 @@ function glob(globOptions) {
|
|
|
84
103
|
data,
|
|
85
104
|
filePath: filePath2
|
|
86
105
|
});
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
if (
|
|
106
|
+
if (existingEntry && existingEntry.filePath && existingEntry.filePath !== relativePath2) {
|
|
107
|
+
const oldFilePath = new URL(existingEntry.filePath, config.root);
|
|
108
|
+
if (existsSync(oldFilePath)) {
|
|
90
109
|
logger.warn(
|
|
91
110
|
`Duplicate id "${id}" found in ${filePath2}. Later items with the same id will overwrite earlier ones.`
|
|
92
111
|
);
|
|
93
112
|
}
|
|
113
|
+
}
|
|
114
|
+
if (entryType.getRenderFunction) {
|
|
115
|
+
let render = renderFunctionByContentType.get(entryType);
|
|
94
116
|
if (!render) {
|
|
95
117
|
render = await entryType.getRenderFunction(config);
|
|
96
118
|
renderFunctionByContentType.set(entryType, render);
|
|
@@ -130,7 +152,12 @@ function glob(globOptions) {
|
|
|
130
152
|
}
|
|
131
153
|
fileToIdMap.set(filePath2, id);
|
|
132
154
|
}
|
|
133
|
-
|
|
155
|
+
let baseDir;
|
|
156
|
+
if (isLegacy && !globOptions.base) {
|
|
157
|
+
baseDir = new URL(`./src/content/${collection}`, config.root);
|
|
158
|
+
} else {
|
|
159
|
+
baseDir = globOptions.base ? new URL(globOptions.base, config.root) : config.root;
|
|
160
|
+
}
|
|
134
161
|
if (!baseDir.pathname.endsWith("/")) {
|
|
135
162
|
baseDir.pathname = `${baseDir.pathname}/`;
|
|
136
163
|
}
|
|
@@ -229,5 +256,6 @@ function glob(globOptions) {
|
|
|
229
256
|
};
|
|
230
257
|
}
|
|
231
258
|
export {
|
|
232
|
-
glob
|
|
259
|
+
glob,
|
|
260
|
+
secretLegacyFlag
|
|
233
261
|
};
|
|
@@ -35,7 +35,11 @@ async function createContentTypesGenerator({
|
|
|
35
35
|
viteServer
|
|
36
36
|
}) {
|
|
37
37
|
const collectionEntryMap = {};
|
|
38
|
-
const contentPaths = getContentPaths(
|
|
38
|
+
const contentPaths = getContentPaths(
|
|
39
|
+
settings.config,
|
|
40
|
+
fs,
|
|
41
|
+
settings.config.legacy?.collectionsBackwardsCompat
|
|
42
|
+
);
|
|
39
43
|
const contentEntryConfigByExt = getEntryConfigByExtMap(settings.contentEntryTypes);
|
|
40
44
|
const contentEntryExts = [...contentEntryConfigByExt.keys()];
|
|
41
45
|
const dataEntryExts = getDataEntryExts(settings);
|
|
@@ -288,10 +292,10 @@ async function typeForCollection(collection, collectionKey) {
|
|
|
288
292
|
if (collection?.schema) {
|
|
289
293
|
return { type: `InferEntrySchema<${collectionKey}>` };
|
|
290
294
|
}
|
|
291
|
-
if (!collection?.type || typeof collection.loader === "function") {
|
|
295
|
+
if (!collection?.type || typeof collection.loader === "function" || !collection.loader) {
|
|
292
296
|
return { type: "any" };
|
|
293
297
|
}
|
|
294
|
-
if (collection.loader.schema) {
|
|
298
|
+
if (typeof collection.loader === "object" && collection.loader.schema) {
|
|
295
299
|
return { type: `InferLoaderSchema<${collectionKey}>` };
|
|
296
300
|
}
|
|
297
301
|
const result = await getCreateSchemaResult(collection, collectionKey);
|
|
@@ -323,7 +327,7 @@ async function writeContentFiles({
|
|
|
323
327
|
fs.mkdirSync(collectionSchemasDir, { recursive: true });
|
|
324
328
|
for (const [collection, config] of Object.entries(contentConfig?.collections ?? {})) {
|
|
325
329
|
collectionEntryMap[JSON.stringify(collection)] ??= {
|
|
326
|
-
type: config.type,
|
|
330
|
+
type: config.type ?? "unknown",
|
|
327
331
|
entries: {}
|
|
328
332
|
};
|
|
329
333
|
}
|
|
@@ -388,8 +392,8 @@ async function writeContentFiles({
|
|
|
388
392
|
hasSchema: Boolean(
|
|
389
393
|
// Is there a user provided schema or
|
|
390
394
|
collectionConfig?.schema || // Is it a loader object and
|
|
391
|
-
typeof collectionConfig?.loader
|
|
392
|
-
(collectionConfig
|
|
395
|
+
typeof collectionConfig?.loader === "object" && // Is it a loader static schema or
|
|
396
|
+
(collectionConfig.loader.schema || // is it a loader dynamic schema
|
|
393
397
|
createSchemaResultCache.has(collectionKey))
|
|
394
398
|
),
|
|
395
399
|
name: key
|
package/dist/content/utils.d.ts
CHANGED
|
@@ -14,6 +14,14 @@ export declare const loaderReturnSchema: z.ZodUnion<readonly [z.ZodArray<z.ZodOb
|
|
|
14
14
|
id: z.ZodOptional<z.ZodString>;
|
|
15
15
|
}, z.core.$loose>>]>;
|
|
16
16
|
declare const collectionConfigParser: z.ZodUnion<readonly [z.ZodObject<{
|
|
17
|
+
type: z.ZodOptional<z.ZodLiteral<"content">>;
|
|
18
|
+
schema: z.ZodOptional<z.ZodAny>;
|
|
19
|
+
loader: z.ZodOptional<z.ZodNever>;
|
|
20
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
21
|
+
type: z.ZodOptional<z.ZodLiteral<"data">>;
|
|
22
|
+
schema: z.ZodOptional<z.ZodAny>;
|
|
23
|
+
loader: z.ZodOptional<z.ZodNever>;
|
|
24
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
17
25
|
type: z.ZodLiteral<"content_layer">;
|
|
18
26
|
schema: z.ZodOptional<z.ZodAny>;
|
|
19
27
|
loader: z.ZodUnion<readonly [z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>, z.ZodObject<{
|
|
@@ -38,6 +46,14 @@ declare const collectionConfigParser: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
38
46
|
}, z.core.$strip>]>;
|
|
39
47
|
declare const contentConfigParser: z.ZodObject<{
|
|
40
48
|
collections: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
|
|
49
|
+
type: z.ZodOptional<z.ZodLiteral<"content">>;
|
|
50
|
+
schema: z.ZodOptional<z.ZodAny>;
|
|
51
|
+
loader: z.ZodOptional<z.ZodNever>;
|
|
52
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
53
|
+
type: z.ZodOptional<z.ZodLiteral<"data">>;
|
|
54
|
+
schema: z.ZodOptional<z.ZodAny>;
|
|
55
|
+
loader: z.ZodOptional<z.ZodNever>;
|
|
56
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
41
57
|
type: z.ZodLiteral<"content_layer">;
|
|
42
58
|
schema: z.ZodOptional<z.ZodAny>;
|
|
43
59
|
loader: z.ZodUnion<readonly [z.ZodFunction<z.core.$ZodFunctionArgs, z.core.$ZodFunctionOut>, z.ZodObject<{
|
|
@@ -158,7 +174,7 @@ export type ContentPaths = {
|
|
|
158
174
|
url: URL;
|
|
159
175
|
};
|
|
160
176
|
};
|
|
161
|
-
export declare function getContentPaths({ srcDir, root }: Pick<AstroConfig, 'root' | 'srcDir'>, fs?: typeof fsMod): ContentPaths;
|
|
177
|
+
export declare function getContentPaths({ srcDir, root }: Pick<AstroConfig, 'root' | 'srcDir'>, fs?: typeof fsMod, legacyCollectionsBackwardsCompat?: boolean): ContentPaths;
|
|
162
178
|
/**
|
|
163
179
|
* Check for slug in content entry frontmatter and validate the type,
|
|
164
180
|
* falling back to the `generatedSlug` if none is found.
|