astro 4.6.1 → 4.6.3
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/astro-jsx.d.ts +0 -2
- package/components/Image.astro +1 -1
- package/components/Picture.astro +2 -2
- package/dist/@types/astro.d.ts +38 -37
- package/dist/assets/endpoint/generic.js +10 -6
- package/dist/assets/endpoint/node.js +1 -1
- package/dist/assets/utils/vendor/image-size/types/svg.js +0 -1
- package/dist/assets/vite-plugin-assets.js +3 -1
- package/dist/cli/add/index.js +6 -6
- package/dist/cli/install-package.js +4 -2
- package/dist/core/build/consts.d.ts +1 -0
- package/dist/core/build/consts.js +4 -0
- package/dist/core/build/generate.js +1 -1
- package/dist/core/build/index.js +2 -1
- package/dist/core/build/internal.d.ts +1 -0
- package/dist/core/build/internal.js +2 -1
- package/dist/core/build/pipeline.js +1 -1
- package/dist/core/build/plugin.d.ts +1 -1
- package/dist/core/build/plugins/plugin-content.js +135 -30
- package/dist/core/build/plugins/util.d.ts +1 -1
- package/dist/core/build/static-build.d.ts +1 -1
- package/dist/core/build/static-build.js +3 -2
- package/dist/core/config/config.d.ts +1 -0
- package/dist/core/config/config.js +10 -8
- package/dist/core/config/index.d.ts +1 -1
- package/dist/core/config/index.js +8 -1
- package/dist/core/config/schema.d.ts +1 -1
- package/dist/core/config/tsconfig.d.ts +1 -1
- package/dist/core/config/tsconfig.js +7 -3
- package/dist/core/constants.js +1 -1
- package/dist/core/create-vite.js +2 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/messages.js +2 -2
- package/dist/core/render-context.d.ts +10 -1
- package/dist/core/render-context.js +38 -8
- package/dist/integrations/index.d.ts +2 -1
- package/dist/integrations/index.js +9 -2
- package/dist/runtime/client/dev-toolbar/apps/settings.js +3 -1
- package/dist/runtime/client/dev-toolbar/entrypoint.js +1 -1
- package/dist/runtime/client/dev-toolbar/toolbar.js +3 -1
- package/dist/runtime/server/render/astro/render.js +3 -0
- package/dist/transitions/router.js +5 -2
- package/dist/vite-plugin-astro/index.js +11 -4
- package/dist/vite-plugin-markdown/index.js +5 -0
- package/package.json +2 -2
package/astro-jsx.d.ts
CHANGED
|
@@ -9,8 +9,6 @@
|
|
|
9
9
|
* Adapted from React’s TypeScript definition from DefinitelyTyped.
|
|
10
10
|
* @see https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts
|
|
11
11
|
*/
|
|
12
|
-
// BUG! Prettier 3.0 removes `declare`: https://github.com/prettier/prettier/issues/15207
|
|
13
|
-
// prettier-ignore
|
|
14
12
|
declare namespace astroHTML.JSX {
|
|
15
13
|
export type Child = Node | Node[] | string | number | boolean | null | undefined | unknown;
|
|
16
14
|
export type Children = Child | Child[];
|
package/components/Image.astro
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
import {
|
|
2
|
+
import { type LocalImageProps, type RemoteImageProps, getImage } from 'astro:assets';
|
|
3
3
|
import { AstroError, AstroErrorData } from '../dist/core/errors/index.js';
|
|
4
4
|
import type { HTMLAttributes } from '../types';
|
|
5
5
|
|
package/components/Picture.astro
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
import {
|
|
2
|
+
import { type LocalImageProps, type RemoteImageProps, getImage } from 'astro:assets';
|
|
3
3
|
import type { GetImageResult, ImageOutputFormat } from '../dist/@types/astro';
|
|
4
4
|
import { isESMImportedImage, resolveSrc } from '../dist/assets/utils/imageKind';
|
|
5
5
|
import { AstroError, AstroErrorData } from '../dist/core/errors/index.js';
|
|
@@ -45,7 +45,7 @@ let resultFallbackFormat = fallbackFormat ?? defaultFallbackFormat;
|
|
|
45
45
|
if (
|
|
46
46
|
!fallbackFormat &&
|
|
47
47
|
isESMImportedImage(originalSrc) &&
|
|
48
|
-
originalSrc.format
|
|
48
|
+
(specialFormatsFallback as ReadonlyArray<string>).includes(originalSrc.format)
|
|
49
49
|
) {
|
|
50
50
|
resultFallbackFormat = originalSrc.format;
|
|
51
51
|
}
|
package/dist/@types/astro.d.ts
CHANGED
|
@@ -1394,18 +1394,18 @@ export interface AstroUserConfig {
|
|
|
1394
1394
|
* When `true`, all URLs will display a language prefix.
|
|
1395
1395
|
* URLs will be of the form `example.com/[locale]/content/` for every route, including the default language.
|
|
1396
1396
|
* Localized folders are used for every language, including the default.
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1397
|
+
*
|
|
1398
|
+
* ```js
|
|
1399
|
+
* export default defineConfig({
|
|
1400
|
+
* i18n: {
|
|
1401
|
+
* defaultLocale: "en",
|
|
1402
|
+
* locales: ["en", "fr", "pt-br", "es"],
|
|
1403
|
+
* routing: {
|
|
1404
|
+
* prefixDefaultLocale: true,
|
|
1405
|
+
* }
|
|
1406
|
+
* }
|
|
1407
|
+
* })
|
|
1408
|
+
* ```
|
|
1409
1409
|
*/
|
|
1410
1410
|
prefixDefaultLocale?: boolean;
|
|
1411
1411
|
/**
|
|
@@ -1446,32 +1446,32 @@ export interface AstroUserConfig {
|
|
|
1446
1446
|
* - `"pathname": The strategy is applied to the pathname of the URLs
|
|
1447
1447
|
*/
|
|
1448
1448
|
strategy?: 'pathname';
|
|
1449
|
-
}
|
|
1449
|
+
}
|
|
1450
1450
|
/**
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1451
|
+
*
|
|
1452
|
+
* @docs
|
|
1453
|
+
* @name i18n.routing.manual
|
|
1454
|
+
* @kind h4
|
|
1455
|
+
* @type {string}
|
|
1456
|
+
* @version 4.6.0
|
|
1457
|
+
* @description
|
|
1458
|
+
* When this option is enabled, Astro will **disable** its i18n middleware so that you can implement your own custom logic. No other `routing` options (e.g. `prefixDefaultLocale`) may be configured with `routing: "manual"`.
|
|
1459
|
+
*
|
|
1460
|
+
* You will be responsible for writing your own routing logic, or executing Astro's i18n middleware manually alongside your own.
|
|
1461
|
+
*
|
|
1462
|
+
* ```js
|
|
1463
|
+
* export default defineConfig({
|
|
1464
|
+
* i18n: {
|
|
1465
|
+
* defaultLocale: "en",
|
|
1466
|
+
* locales: ["en", "fr", "pt-br", "es"],
|
|
1467
|
+
* routing: {
|
|
1468
|
+
* prefixDefaultLocale: true,
|
|
1469
|
+
* }
|
|
1470
|
+
* }
|
|
1471
|
+
* })
|
|
1472
|
+
* ```
|
|
1473
|
+
*/
|
|
1474
|
+
| 'manual';
|
|
1475
1475
|
/**
|
|
1476
1476
|
* @name i18n.domains
|
|
1477
1477
|
* @type {Record<string, string> }
|
|
@@ -2524,6 +2524,7 @@ export interface AstroIntegration {
|
|
|
2524
2524
|
dir: URL;
|
|
2525
2525
|
routes: RouteData[];
|
|
2526
2526
|
logger: AstroIntegrationLogger;
|
|
2527
|
+
cacheManifest: boolean;
|
|
2527
2528
|
}) => void | Promise<void>;
|
|
2528
2529
|
};
|
|
2529
2530
|
}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
import { imageConfig } from "astro:assets";
|
|
1
2
|
import { isRemotePath } from "@astrojs/internal-helpers/path";
|
|
2
3
|
import mime from "mime/lite.js";
|
|
3
4
|
import { getConfiguredImageService } from "../internal.js";
|
|
4
5
|
import { etag } from "../utils/etag.js";
|
|
5
6
|
import { isRemoteAllowed } from "../utils/remotePattern.js";
|
|
6
|
-
|
|
7
|
-
async function loadRemoteImage(src) {
|
|
7
|
+
async function loadRemoteImage(src, headers) {
|
|
8
8
|
try {
|
|
9
|
-
const res = await fetch(src
|
|
9
|
+
const res = await fetch(src, {
|
|
10
|
+
// Forward all headers from the original request
|
|
11
|
+
headers
|
|
12
|
+
});
|
|
10
13
|
if (!res.ok) {
|
|
11
14
|
return void 0;
|
|
12
15
|
}
|
|
@@ -27,11 +30,12 @@ const GET = async ({ request }) => {
|
|
|
27
30
|
throw new Error("Incorrect transform returned by `parseURL`");
|
|
28
31
|
}
|
|
29
32
|
let inputBuffer = void 0;
|
|
30
|
-
const
|
|
31
|
-
|
|
33
|
+
const isRemoteImage = isRemotePath(transform.src);
|
|
34
|
+
const sourceUrl = isRemoteImage ? new URL(transform.src) : new URL(transform.src, url.origin);
|
|
35
|
+
if (isRemoteImage && isRemoteAllowed(transform.src, imageConfig) === false) {
|
|
32
36
|
return new Response("Forbidden", { status: 403 });
|
|
33
37
|
}
|
|
34
|
-
inputBuffer = await loadRemoteImage(sourceUrl);
|
|
38
|
+
inputBuffer = await loadRemoteImage(sourceUrl, isRemoteImage ? new Headers() : request.headers);
|
|
35
39
|
if (!inputBuffer) {
|
|
36
40
|
return new Response("Not Found", { status: 404 });
|
|
37
41
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import os from "node:os";
|
|
2
2
|
import { isAbsolute } from "node:path";
|
|
3
3
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
4
|
+
import { assetsDir, imageConfig, outDir } from "astro:assets";
|
|
4
5
|
import { isRemotePath, removeQueryString } from "@astrojs/internal-helpers/path";
|
|
5
6
|
import { readFile } from "fs/promises";
|
|
6
7
|
import mime from "mime/lite.js";
|
|
7
8
|
import { getConfiguredImageService } from "../internal.js";
|
|
8
9
|
import { etag } from "../utils/etag.js";
|
|
9
10
|
import { isRemoteAllowed } from "../utils/remotePattern.js";
|
|
10
|
-
import { assetsDir, imageConfig, outDir } from "astro:assets";
|
|
11
11
|
function replaceFileSystemReferences(src) {
|
|
12
12
|
return os.platform().includes("win32") ? src.replace(/^\/@fs\//, "") : src.replace(/^\/@fs/, "");
|
|
13
13
|
}
|
|
@@ -41,7 +41,6 @@ function parseAttributes(root) {
|
|
|
41
41
|
const viewbox = root.match(extractorRegExps.viewbox);
|
|
42
42
|
return {
|
|
43
43
|
height: height && parseLength(height[2]),
|
|
44
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
45
44
|
viewbox: viewbox && parseViewbox(viewbox[2]),
|
|
46
45
|
width: width && parseLength(width[2])
|
|
47
46
|
};
|
|
@@ -113,7 +113,9 @@ function assets({
|
|
|
113
113
|
isServerLikeOutput(settings.config) ? settings.config.build.client : settings.config.outDir
|
|
114
114
|
)
|
|
115
115
|
)});
|
|
116
|
-
export const assetsDir = /* #__PURE__ */ new URL(${JSON.stringify(
|
|
116
|
+
export const assetsDir = /* #__PURE__ */ new URL(${JSON.stringify(
|
|
117
|
+
settings.config.build.assets
|
|
118
|
+
)}, outDir);
|
|
117
119
|
export const getImage = async (options) => await getImageInternal(options, imageConfig);
|
|
118
120
|
`;
|
|
119
121
|
}
|
package/dist/cli/add/index.js
CHANGED
|
@@ -126,12 +126,12 @@ async function add(names, { flags }) {
|
|
|
126
126
|
["node", "astro add node"]
|
|
127
127
|
],
|
|
128
128
|
Others: [
|
|
129
|
+
["db", "astro add db"],
|
|
129
130
|
["tailwind", "astro add tailwind"],
|
|
130
|
-
["image", "astro add image"],
|
|
131
131
|
["mdx", "astro add mdx"],
|
|
132
|
+
["markdoc", "astro add markdoc"],
|
|
132
133
|
["partytown", "astro add partytown"],
|
|
133
|
-
["sitemap", "astro add sitemap"]
|
|
134
|
-
["prefetch", "astro add prefetch"]
|
|
134
|
+
["sitemap", "astro add sitemap"]
|
|
135
135
|
]
|
|
136
136
|
},
|
|
137
137
|
description: `For more integrations, check out: ${cyan("https://astro.build/integrations")}`
|
|
@@ -823,14 +823,14 @@ async function updateTSConfig(cwd = process.cwd(), logger, integrationsInfo, fla
|
|
|
823
823
|
inputConfig = {
|
|
824
824
|
tsconfig: defaultTSConfig,
|
|
825
825
|
tsconfigFile: path.join(cwd, "tsconfig.json"),
|
|
826
|
-
rawConfig:
|
|
826
|
+
rawConfig: defaultTSConfig
|
|
827
827
|
};
|
|
828
828
|
} else {
|
|
829
|
-
inputConfigText = JSON.stringify(inputConfig.rawConfig
|
|
829
|
+
inputConfigText = JSON.stringify(inputConfig.rawConfig, null, 2);
|
|
830
830
|
}
|
|
831
831
|
const configFileName = path.basename(inputConfig.tsconfigFile);
|
|
832
832
|
const outputConfig = updateTSConfigForFramework(
|
|
833
|
-
inputConfig.rawConfig
|
|
833
|
+
inputConfig.rawConfig,
|
|
834
834
|
firstIntegrationWithTSSettings
|
|
835
835
|
);
|
|
836
836
|
const output = JSON.stringify(outputConfig, null, 2);
|
|
@@ -26,7 +26,9 @@ async function getPackage(packageName, logger, options, otherDeps = []) {
|
|
|
26
26
|
} catch (e) {
|
|
27
27
|
if (options.optional)
|
|
28
28
|
return void 0;
|
|
29
|
-
let message = `To continue, Astro requires the following dependency to be installed: ${bold(
|
|
29
|
+
let message = `To continue, Astro requires the following dependency to be installed: ${bold(
|
|
30
|
+
packageName
|
|
31
|
+
)}.`;
|
|
30
32
|
if (ci.isCI) {
|
|
31
33
|
message += ` Packages cannot be installed automatically in CI environments.`;
|
|
32
34
|
}
|
|
@@ -76,7 +78,7 @@ function getInstallCommand(packages, packageManager) {
|
|
|
76
78
|
}
|
|
77
79
|
async function installPackage(packageNames, options, logger) {
|
|
78
80
|
const cwd = options.cwd ?? process.cwd();
|
|
79
|
-
const packageManager = (await whichPm(cwd))
|
|
81
|
+
const packageManager = (await whichPm(cwd))?.name ?? "npm";
|
|
80
82
|
const installCommand = getInstallCommand(packageNames, packageManager);
|
|
81
83
|
if (!installCommand) {
|
|
82
84
|
return false;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const CHUNKS_PATH = "chunks/";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
|
-
import { bgGreen, black, blue, bold, dim, green, magenta
|
|
4
|
+
import { bgGreen, black, blue, bold, dim, green, magenta } from "kleur/colors";
|
|
5
5
|
import PQueue from "p-queue";
|
|
6
6
|
import {
|
|
7
7
|
generateImagesForPath,
|
package/dist/core/build/index.js
CHANGED
|
@@ -146,7 +146,8 @@ class AstroBuilder {
|
|
|
146
146
|
config: this.settings.config,
|
|
147
147
|
pages: pageNames,
|
|
148
148
|
routes: Object.values(allPages).flat().map((pageData) => pageData.route),
|
|
149
|
-
logging: this.logger
|
|
149
|
+
logging: this.logger,
|
|
150
|
+
cacheManifest: internals.cacheManifestUsed
|
|
150
151
|
});
|
|
151
152
|
if (this.logger.level && levels[this.logger.level()] <= levels["info"]) {
|
|
152
153
|
await this.printStats({
|
|
@@ -66,6 +66,7 @@ export interface BuildInternals {
|
|
|
66
66
|
*/
|
|
67
67
|
discoveredScripts: Set<string>;
|
|
68
68
|
cachedClientEntries: string[];
|
|
69
|
+
cacheManifestUsed: boolean;
|
|
69
70
|
propagatedStylesMap: Map<string, Set<StylesheetAsset>>;
|
|
70
71
|
propagatedScriptsMap: Map<string, Set<string>>;
|
|
71
72
|
staticFiles: Set<string>;
|
|
@@ -29,7 +29,8 @@ function createBuildInternals() {
|
|
|
29
29
|
staticFiles: /* @__PURE__ */ new Set(),
|
|
30
30
|
componentMetadata: /* @__PURE__ */ new Map(),
|
|
31
31
|
ssrSplitEntryChunks: /* @__PURE__ */ new Map(),
|
|
32
|
-
entryPoints: /* @__PURE__ */ new Map()
|
|
32
|
+
entryPoints: /* @__PURE__ */ new Map(),
|
|
33
|
+
cacheManifestUsed: false
|
|
33
34
|
};
|
|
34
35
|
}
|
|
35
36
|
function trackPageData(internals, component, pageData, componentModuleId, componentURL) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Plugin as VitePlugin
|
|
1
|
+
import type { Rollup, Plugin as VitePlugin } from 'vite';
|
|
2
2
|
import type { BuildInternals } from './internal.js';
|
|
3
3
|
import type { StaticBuildOptions, ViteBuildReturn } from './types.js';
|
|
4
4
|
type RollupOutputArray = Extract<ViteBuildReturn, Array<any>>;
|
|
@@ -10,40 +10,53 @@ import {
|
|
|
10
10
|
generateLookupMap
|
|
11
11
|
} from "../../../content/vite-plugin-content-virtual-mod.js";
|
|
12
12
|
import { isServerLikeOutput } from "../../../prerender/utils.js";
|
|
13
|
-
import {
|
|
13
|
+
import { configPaths } from "../../config/index.js";
|
|
14
|
+
import { emptyDir } from "../../fs/index.js";
|
|
15
|
+
import {
|
|
16
|
+
appendForwardSlash,
|
|
17
|
+
joinPaths,
|
|
18
|
+
removeFileExtension,
|
|
19
|
+
removeLeadingForwardSlash
|
|
20
|
+
} from "../../path.js";
|
|
14
21
|
import { addRollupInput } from "../add-rollup-input.js";
|
|
22
|
+
import { CHUNKS_PATH } from "../consts.js";
|
|
15
23
|
import {} from "../internal.js";
|
|
16
24
|
import { copyFiles } from "../static-build.js";
|
|
17
25
|
import { encodeName } from "../util.js";
|
|
18
26
|
import { extendManualChunks } from "./util.js";
|
|
19
27
|
const CONTENT_CACHE_DIR = "./content/";
|
|
20
28
|
const CONTENT_MANIFEST_FILE = "./manifest.json";
|
|
21
|
-
const CONTENT_MANIFEST_VERSION =
|
|
29
|
+
const CONTENT_MANIFEST_VERSION = 1;
|
|
22
30
|
const virtualEmptyModuleId = `virtual:empty-content`;
|
|
23
31
|
const resolvedVirtualEmptyModuleId = `\0${virtualEmptyModuleId}`;
|
|
32
|
+
const NO_MANIFEST_VERSION = -1;
|
|
24
33
|
function createContentManifest() {
|
|
25
|
-
return {
|
|
34
|
+
return {
|
|
35
|
+
version: NO_MANIFEST_VERSION,
|
|
36
|
+
entries: [],
|
|
37
|
+
serverEntries: [],
|
|
38
|
+
clientEntries: [],
|
|
39
|
+
lockfiles: "",
|
|
40
|
+
configs: ""
|
|
41
|
+
};
|
|
26
42
|
}
|
|
27
|
-
function vitePluginContent(opts, lookupMap, internals) {
|
|
43
|
+
function vitePluginContent(opts, lookupMap, internals, cachedBuildOutput) {
|
|
28
44
|
const { config } = opts.settings;
|
|
29
45
|
const { cacheDir } = config;
|
|
30
46
|
const distRoot = config.outDir;
|
|
31
47
|
const distContentRoot = new URL("./content/", distRoot);
|
|
32
|
-
const cachedChunks = new URL("./chunks/", opts.settings.config.cacheDir);
|
|
33
|
-
const distChunks = new URL("./chunks/", opts.settings.config.outDir);
|
|
34
48
|
const contentCacheDir = new URL(CONTENT_CACHE_DIR, cacheDir);
|
|
35
49
|
const contentManifestFile = new URL(CONTENT_MANIFEST_FILE, contentCacheDir);
|
|
36
|
-
const
|
|
37
|
-
const cacheTmp = new URL("./.tmp/", cache);
|
|
50
|
+
const cacheTmp = new URL("./.tmp/", contentCacheDir);
|
|
38
51
|
let oldManifest = createContentManifest();
|
|
39
52
|
let newManifest = createContentManifest();
|
|
40
53
|
let entries;
|
|
41
54
|
let injectedEmptyFile = false;
|
|
55
|
+
let currentManifestState = "valid";
|
|
42
56
|
if (fsMod.existsSync(contentManifestFile)) {
|
|
43
57
|
try {
|
|
44
58
|
const data = fsMod.readFileSync(contentManifestFile, { encoding: "utf8" });
|
|
45
59
|
oldManifest = JSON.parse(data);
|
|
46
|
-
internals.cachedClientEntries = oldManifest.clientEntries;
|
|
47
60
|
} catch {
|
|
48
61
|
}
|
|
49
62
|
}
|
|
@@ -53,6 +66,30 @@ function vitePluginContent(opts, lookupMap, internals) {
|
|
|
53
66
|
let newOptions = Object.assign({}, options);
|
|
54
67
|
newManifest = await generateContentManifest(opts, lookupMap);
|
|
55
68
|
entries = getEntriesFromManifests(oldManifest, newManifest);
|
|
69
|
+
currentManifestState = manifestState(oldManifest, newManifest);
|
|
70
|
+
if (currentManifestState === "valid") {
|
|
71
|
+
internals.cachedClientEntries = oldManifest.clientEntries;
|
|
72
|
+
} else {
|
|
73
|
+
let logReason = "";
|
|
74
|
+
switch (currentManifestState) {
|
|
75
|
+
case "config-mismatch":
|
|
76
|
+
logReason = "Astro config has changed";
|
|
77
|
+
break;
|
|
78
|
+
case "lockfile-mismatch":
|
|
79
|
+
logReason = "Lockfiles have changed";
|
|
80
|
+
break;
|
|
81
|
+
case "no-entries":
|
|
82
|
+
logReason = "No content collections entries cached";
|
|
83
|
+
break;
|
|
84
|
+
case "version-mismatch":
|
|
85
|
+
logReason = "The cache manifest version has changed";
|
|
86
|
+
break;
|
|
87
|
+
case "no-manifest":
|
|
88
|
+
logReason = "No content manifest was found in the cache";
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
opts.logger.info("build", `Cache invalid, rebuilding from source. Reason: ${logReason}.`);
|
|
92
|
+
}
|
|
56
93
|
for (const { type, entry } of entries.buildFromSource) {
|
|
57
94
|
const fileURL = encodeURI(joinPaths(opts.settings.config.root.toString(), entry));
|
|
58
95
|
const input = fileURLToPath(fileURL);
|
|
@@ -62,8 +99,12 @@ function vitePluginContent(opts, lookupMap, internals) {
|
|
|
62
99
|
}
|
|
63
100
|
newOptions = addRollupInput(newOptions, inputs);
|
|
64
101
|
}
|
|
65
|
-
if (
|
|
66
|
-
|
|
102
|
+
if (currentManifestState === "valid") {
|
|
103
|
+
for (const { cached, dist } of cachedBuildOutput) {
|
|
104
|
+
if (fsMod.existsSync(cached)) {
|
|
105
|
+
await copyFiles(cached, dist, true);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
67
108
|
}
|
|
68
109
|
if (entries.buildFromSource.length === 0) {
|
|
69
110
|
newOptions = addRollupInput(newOptions, [virtualEmptyModuleId]);
|
|
@@ -152,15 +193,17 @@ export default {}`
|
|
|
152
193
|
]);
|
|
153
194
|
newManifest.serverEntries = Array.from(serverComponents);
|
|
154
195
|
newManifest.clientEntries = Array.from(clientComponents);
|
|
196
|
+
const cacheExists = fsMod.existsSync(contentCacheDir);
|
|
197
|
+
if (cacheExists && currentManifestState !== "valid") {
|
|
198
|
+
emptyDir(contentCacheDir);
|
|
199
|
+
}
|
|
155
200
|
await fsMod.promises.mkdir(contentCacheDir, { recursive: true });
|
|
156
201
|
await fsMod.promises.writeFile(contentManifestFile, JSON.stringify(newManifest), {
|
|
157
202
|
encoding: "utf8"
|
|
158
203
|
});
|
|
159
|
-
const cacheExists = fsMod.existsSync(cache);
|
|
160
|
-
fsMod.mkdirSync(cache, { recursive: true });
|
|
161
204
|
await fsMod.promises.mkdir(cacheTmp, { recursive: true });
|
|
162
205
|
await copyFiles(distContentRoot, cacheTmp, true);
|
|
163
|
-
if (cacheExists) {
|
|
206
|
+
if (cacheExists && currentManifestState === "valid") {
|
|
164
207
|
await copyFiles(contentCacheDir, distContentRoot, false);
|
|
165
208
|
}
|
|
166
209
|
await copyFiles(cacheTmp, contentCacheDir);
|
|
@@ -186,11 +229,11 @@ function findEntryFromSrcRelativePath(lookupMap, srcRelativePath) {
|
|
|
186
229
|
}
|
|
187
230
|
}
|
|
188
231
|
function getEntriesFromManifests(oldManifest, newManifest) {
|
|
189
|
-
const {
|
|
190
|
-
const {
|
|
232
|
+
const { entries: oldEntries } = oldManifest;
|
|
233
|
+
const { entries: newEntries } = newManifest;
|
|
191
234
|
let entries = { restoreFromCache: [], buildFromSource: [] };
|
|
192
235
|
const newEntryMap = new Map(newEntries);
|
|
193
|
-
if (
|
|
236
|
+
if (manifestState(oldManifest, newManifest) !== "valid") {
|
|
194
237
|
entries.buildFromSource = Array.from(newEntryMap.keys());
|
|
195
238
|
return entries;
|
|
196
239
|
}
|
|
@@ -206,13 +249,27 @@ function getEntriesFromManifests(oldManifest, newManifest) {
|
|
|
206
249
|
}
|
|
207
250
|
return entries;
|
|
208
251
|
}
|
|
252
|
+
function manifestState(oldManifest, newManifest) {
|
|
253
|
+
if (oldManifest.version === NO_MANIFEST_VERSION) {
|
|
254
|
+
return "no-manifest";
|
|
255
|
+
}
|
|
256
|
+
if (oldManifest.version !== newManifest.version) {
|
|
257
|
+
return "version-mismatch";
|
|
258
|
+
}
|
|
259
|
+
if (oldManifest.entries.length === 0) {
|
|
260
|
+
return "no-entries";
|
|
261
|
+
}
|
|
262
|
+
if (oldManifest.lockfiles !== newManifest.lockfiles || newManifest.lockfiles === "") {
|
|
263
|
+
return "lockfile-mismatch";
|
|
264
|
+
}
|
|
265
|
+
if (oldManifest.configs !== newManifest.configs) {
|
|
266
|
+
return "config-mismatch";
|
|
267
|
+
}
|
|
268
|
+
return "valid";
|
|
269
|
+
}
|
|
209
270
|
async function generateContentManifest(opts, lookupMap) {
|
|
210
|
-
let manifest =
|
|
211
|
-
|
|
212
|
-
entries: [],
|
|
213
|
-
serverEntries: [],
|
|
214
|
-
clientEntries: []
|
|
215
|
-
};
|
|
271
|
+
let manifest = createContentManifest();
|
|
272
|
+
manifest.version = CONTENT_MANIFEST_VERSION;
|
|
216
273
|
const limit = pLimit(10);
|
|
217
274
|
const promises = [];
|
|
218
275
|
for (const [collection, { type, entries }] of Object.entries(lookupMap)) {
|
|
@@ -227,19 +284,65 @@ async function generateContentManifest(opts, lookupMap) {
|
|
|
227
284
|
);
|
|
228
285
|
}
|
|
229
286
|
}
|
|
287
|
+
const [lockfiles, configs] = await Promise.all([
|
|
288
|
+
lockfilesHash(opts.settings.config.root),
|
|
289
|
+
configHash(opts.settings.config.root)
|
|
290
|
+
]);
|
|
291
|
+
manifest.lockfiles = lockfiles;
|
|
292
|
+
manifest.configs = configs;
|
|
230
293
|
await Promise.all(promises);
|
|
231
294
|
return manifest;
|
|
232
295
|
}
|
|
233
|
-
function
|
|
234
|
-
|
|
296
|
+
async function pushBufferInto(fileURL, buffers) {
|
|
297
|
+
try {
|
|
298
|
+
const handle = await fsMod.promises.open(fileURL, "r");
|
|
299
|
+
const data = await handle.readFile();
|
|
300
|
+
buffers.push(data);
|
|
301
|
+
await handle.close();
|
|
302
|
+
} catch {
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
async function lockfilesHash(root) {
|
|
306
|
+
const lockfiles = ["package-lock.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb"];
|
|
307
|
+
const datas = [];
|
|
308
|
+
const promises = [];
|
|
309
|
+
for (const lockfileName of lockfiles) {
|
|
310
|
+
const fileURL = new URL(`./${lockfileName}`, root);
|
|
311
|
+
promises.push(pushBufferInto(fileURL, datas));
|
|
312
|
+
}
|
|
313
|
+
await Promise.all(promises);
|
|
314
|
+
return checksum(...datas);
|
|
315
|
+
}
|
|
316
|
+
async function configHash(root) {
|
|
317
|
+
const configFileNames = configPaths;
|
|
318
|
+
for (const configPath of configFileNames) {
|
|
319
|
+
try {
|
|
320
|
+
const fileURL = new URL(`./${configPath}`, root);
|
|
321
|
+
const data = await fsMod.promises.readFile(fileURL);
|
|
322
|
+
const hash = checksum(data);
|
|
323
|
+
return hash;
|
|
324
|
+
} catch {
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return checksum(`export default {}`);
|
|
328
|
+
}
|
|
329
|
+
function checksum(...datas) {
|
|
330
|
+
const hash = createHash("sha1");
|
|
331
|
+
datas.forEach((data) => hash.update(data));
|
|
332
|
+
return hash.digest("base64");
|
|
235
333
|
}
|
|
236
334
|
function collectionTypeToFlag(type) {
|
|
237
335
|
const name = type[0].toUpperCase() + type.slice(1);
|
|
238
336
|
return `astro${name}CollectionEntry`;
|
|
239
337
|
}
|
|
240
338
|
function pluginContent(opts, internals) {
|
|
241
|
-
const
|
|
242
|
-
const
|
|
339
|
+
const { cacheDir, outDir } = opts.settings.config;
|
|
340
|
+
const chunksFolder = "./" + CHUNKS_PATH;
|
|
341
|
+
const assetsFolder = "./" + appendForwardSlash(opts.settings.config.build.assets);
|
|
342
|
+
const cachedBuildOutput = [
|
|
343
|
+
{ cached: new URL(chunksFolder, cacheDir), dist: new URL(chunksFolder, outDir) },
|
|
344
|
+
{ cached: new URL(assetsFolder, cacheDir), dist: new URL(assetsFolder, outDir) }
|
|
345
|
+
];
|
|
243
346
|
return {
|
|
244
347
|
targets: ["server"],
|
|
245
348
|
hooks: {
|
|
@@ -252,7 +355,7 @@ function pluginContent(opts, internals) {
|
|
|
252
355
|
}
|
|
253
356
|
const lookupMap = await generateLookupMap({ settings: opts.settings, fs: fsMod });
|
|
254
357
|
return {
|
|
255
|
-
vitePlugin: vitePluginContent(opts, lookupMap, internals)
|
|
358
|
+
vitePlugin: vitePluginContent(opts, lookupMap, internals, cachedBuildOutput)
|
|
256
359
|
};
|
|
257
360
|
},
|
|
258
361
|
async "build:post"() {
|
|
@@ -262,8 +365,10 @@ function pluginContent(opts, internals) {
|
|
|
262
365
|
if (isServerLikeOutput(opts.settings.config)) {
|
|
263
366
|
return;
|
|
264
367
|
}
|
|
265
|
-
|
|
266
|
-
|
|
368
|
+
for (const { cached, dist } of cachedBuildOutput) {
|
|
369
|
+
if (fsMod.existsSync(dist)) {
|
|
370
|
+
await copyFiles(dist, cached, true);
|
|
371
|
+
}
|
|
267
372
|
}
|
|
268
373
|
}
|
|
269
374
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BuildOptions, Plugin as VitePlugin
|
|
1
|
+
import type { BuildOptions, Rollup, Plugin as VitePlugin } from 'vite';
|
|
2
2
|
type OutputOptionsHook = Extract<VitePlugin['outputOptions'], Function>;
|
|
3
3
|
type OutputOptions = Parameters<OutputOptionsHook>[0];
|
|
4
4
|
type ExtendManualChunksHooks = {
|
|
@@ -6,7 +6,7 @@ export declare function viteBuild(opts: StaticBuildOptions): Promise<{
|
|
|
6
6
|
ssrOutputChunkNames: string[];
|
|
7
7
|
}>;
|
|
8
8
|
export declare function staticBuild(opts: StaticBuildOptions, internals: BuildInternals, ssrOutputChunkNames: string[]): Promise<void>;
|
|
9
|
-
export declare function copyFiles(fromFolder: URL, toFolder: URL, includeDotfiles?: boolean): Promise<void>;
|
|
9
|
+
export declare function copyFiles(fromFolder: URL, toFolder: URL, includeDotfiles?: boolean): Promise<void[] | undefined>;
|
|
10
10
|
/**
|
|
11
11
|
* This function takes the virtual module name of any page entrypoint and
|
|
12
12
|
* transforms it to generate a final `.mjs` output file.
|
|
@@ -21,6 +21,7 @@ import { PAGE_SCRIPT_ID } from "../../vite-plugin-scripts/index.js";
|
|
|
21
21
|
import { AstroError, AstroErrorData } from "../errors/index.js";
|
|
22
22
|
import { routeIsRedirect } from "../redirects/index.js";
|
|
23
23
|
import { getOutDirWithinCwd } from "./common.js";
|
|
24
|
+
import { CHUNKS_PATH } from "./consts.js";
|
|
24
25
|
import { generatePages } from "./generate.js";
|
|
25
26
|
import { trackPageData } from "./internal.js";
|
|
26
27
|
import { createPluginContainer } from "./plugin.js";
|
|
@@ -146,7 +147,7 @@ async function ssrBuild(opts, internals, input, container) {
|
|
|
146
147
|
// We need to keep these separate
|
|
147
148
|
chunkFileNames(chunkInfo) {
|
|
148
149
|
const { name } = chunkInfo;
|
|
149
|
-
let prefix =
|
|
150
|
+
let prefix = CHUNKS_PATH;
|
|
150
151
|
let suffix = "_[hash].mjs";
|
|
151
152
|
if (isContentCache) {
|
|
152
153
|
prefix += `${buildID}/`;
|
|
@@ -345,7 +346,7 @@ async function copyFiles(fromFolder, toFolder, includeDotfiles = false) {
|
|
|
345
346
|
});
|
|
346
347
|
if (files.length === 0)
|
|
347
348
|
return;
|
|
348
|
-
await Promise.all(
|
|
349
|
+
return await Promise.all(
|
|
349
350
|
files.map(async function copyFile(filename) {
|
|
350
351
|
const from = new URL(filename, fromFolder);
|
|
351
352
|
const to = new URL(filename, toFolder);
|
|
@@ -7,6 +7,7 @@ export declare function validateConfig(userConfig: any, root: string, cmd: strin
|
|
|
7
7
|
/** Convert the generic "yargs" flag object into our own, custom TypeScript object. */
|
|
8
8
|
export declare function resolveFlags(flags: Partial<Flags>): CLIFlags;
|
|
9
9
|
export declare function resolveRoot(cwd?: string | URL): string;
|
|
10
|
+
export declare const configPaths: readonly string[];
|
|
10
11
|
interface ResolveConfigPathOptions {
|
|
11
12
|
root: string;
|
|
12
13
|
configFile?: string;
|
|
@@ -45,15 +45,16 @@ function resolveRoot(cwd) {
|
|
|
45
45
|
}
|
|
46
46
|
return cwd ? path.resolve(cwd) : process.cwd();
|
|
47
47
|
}
|
|
48
|
+
const configPaths = Object.freeze([
|
|
49
|
+
"astro.config.mjs",
|
|
50
|
+
"astro.config.js",
|
|
51
|
+
"astro.config.ts",
|
|
52
|
+
"astro.config.mts",
|
|
53
|
+
"astro.config.cjs",
|
|
54
|
+
"astro.config.cts"
|
|
55
|
+
]);
|
|
48
56
|
async function search(fsMod, root) {
|
|
49
|
-
const paths =
|
|
50
|
-
"astro.config.mjs",
|
|
51
|
-
"astro.config.js",
|
|
52
|
-
"astro.config.ts",
|
|
53
|
-
"astro.config.mts",
|
|
54
|
-
"astro.config.cjs",
|
|
55
|
-
"astro.config.cts"
|
|
56
|
-
].map((p) => path.join(root, p));
|
|
57
|
+
const paths = configPaths.map((p) => path.join(root, p));
|
|
57
58
|
for (const file of paths) {
|
|
58
59
|
if (fsMod.existsSync(file)) {
|
|
59
60
|
return file;
|
|
@@ -121,6 +122,7 @@ async function resolveConfig(inlineConfig, command, fsMod = fs) {
|
|
|
121
122
|
return { userConfig, astroConfig };
|
|
122
123
|
}
|
|
123
124
|
export {
|
|
125
|
+
configPaths,
|
|
124
126
|
resolveConfig,
|
|
125
127
|
resolveConfigPath,
|
|
126
128
|
resolveFlags,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { resolveConfig, resolveConfigPath, resolveFlags, resolveRoot } from './config.js';
|
|
1
|
+
export { configPaths, resolveConfig, resolveConfigPath, resolveFlags, resolveRoot, } from './config.js';
|
|
2
2
|
export { createNodeLogger } from './logging.js';
|
|
3
3
|
export { mergeConfig } from './merge.js';
|
|
4
4
|
export type { AstroConfigType } from './schema.js';
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
configPaths,
|
|
3
|
+
resolveConfig,
|
|
4
|
+
resolveConfigPath,
|
|
5
|
+
resolveFlags,
|
|
6
|
+
resolveRoot
|
|
7
|
+
} from "./config.js";
|
|
2
8
|
import { createNodeLogger } from "./logging.js";
|
|
3
9
|
import { mergeConfig } from "./merge.js";
|
|
4
10
|
import { createSettings } from "./settings.js";
|
|
5
11
|
import { loadTSConfig, updateTSConfigForFramework } from "./tsconfig.js";
|
|
6
12
|
export {
|
|
13
|
+
configPaths,
|
|
7
14
|
createNodeLogger,
|
|
8
15
|
createSettings,
|
|
9
16
|
loadTSConfig,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
2
|
/// <reference types="node" resolution-mode="require"/>
|
|
3
|
-
import type { RehypePlugin as _RehypePlugin, RemarkPlugin as _RemarkPlugin, RemarkRehype as _RemarkRehype
|
|
3
|
+
import type { ShikiConfig, RehypePlugin as _RehypePlugin, RemarkPlugin as _RemarkPlugin, RemarkRehype as _RemarkRehype } from '@astrojs/markdown-remark';
|
|
4
4
|
import type { ViteUserConfig } from '../../@types/astro.js';
|
|
5
5
|
import type { OutgoingHttpHeaders } from 'node:http';
|
|
6
6
|
import { z } from 'zod';
|
|
@@ -10,7 +10,7 @@ type TSConfigResult<T = {}> = Promise<(TSConfckParseResult & T) | 'invalid-confi
|
|
|
10
10
|
* @param findUp Whether to search for the config file in parent directories, by default only the root directory is searched.
|
|
11
11
|
*/
|
|
12
12
|
export declare function loadTSConfig(root: string | undefined, findUp?: boolean): Promise<TSConfigResult<{
|
|
13
|
-
rawConfig:
|
|
13
|
+
rawConfig: TSConfig;
|
|
14
14
|
}>>;
|
|
15
15
|
export declare function updateTSConfigForFramework(target: TSConfig, framework: frameworkWithTSSettings): TSConfig;
|
|
16
16
|
export type StripEnums<T extends Record<string, any>> = {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
1
2
|
import { join } from "node:path";
|
|
2
3
|
import {
|
|
3
4
|
TSConfckParseError,
|
|
4
5
|
find,
|
|
5
|
-
parse
|
|
6
|
+
parse,
|
|
7
|
+
toJson
|
|
6
8
|
} from "tsconfck";
|
|
7
9
|
const defaultTSConfig = { extends: "astro/tsconfigs/base" };
|
|
8
10
|
const presets = /* @__PURE__ */ new Map([
|
|
@@ -64,14 +66,16 @@ async function loadTSConfig(root, findUp = false) {
|
|
|
64
66
|
if (typeof parsedConfig === "string") {
|
|
65
67
|
return parsedConfig;
|
|
66
68
|
}
|
|
67
|
-
|
|
69
|
+
const rawConfig = await readFile(tsconfig, "utf-8").then(toJson).then((content) => JSON.parse(content));
|
|
70
|
+
return { ...parsedConfig, rawConfig };
|
|
68
71
|
}
|
|
69
72
|
if (jsconfig) {
|
|
70
73
|
const parsedConfig = await safeParse(jsconfig, { root });
|
|
71
74
|
if (typeof parsedConfig === "string") {
|
|
72
75
|
return parsedConfig;
|
|
73
76
|
}
|
|
74
|
-
|
|
77
|
+
const rawConfig = await readFile(jsconfig, "utf-8").then(toJson).then((content) => JSON.parse(content));
|
|
78
|
+
return { ...parsedConfig, rawConfig };
|
|
75
79
|
}
|
|
76
80
|
return "missing-config";
|
|
77
81
|
}
|
package/dist/core/constants.js
CHANGED
package/dist/core/create-vite.js
CHANGED
|
@@ -180,7 +180,8 @@ async function createVite(commandConfig, { settings, logger, mode, command, fs =
|
|
|
180
180
|
ssr: {
|
|
181
181
|
noExternal: [...ALWAYS_NOEXTERNAL, ...astroPkgsConfig.ssr.noExternal],
|
|
182
182
|
external: [...mode === "dev" ? ONLY_DEV_EXTERNAL : [], ...astroPkgsConfig.ssr.external]
|
|
183
|
-
}
|
|
183
|
+
},
|
|
184
|
+
build: { assetsDir: settings.config.build.assets }
|
|
184
185
|
};
|
|
185
186
|
const assetsPrefix = settings.config.build.assetsPrefix;
|
|
186
187
|
if (assetsPrefix) {
|
package/dist/core/dev/dev.js
CHANGED
|
@@ -23,7 +23,7 @@ async function dev(inlineConfig) {
|
|
|
23
23
|
base: restart.container.settings.config.base
|
|
24
24
|
})
|
|
25
25
|
);
|
|
26
|
-
const currentVersion = "4.6.
|
|
26
|
+
const currentVersion = "4.6.3";
|
|
27
27
|
if (currentVersion.includes("-")) {
|
|
28
28
|
logger.warn("SKIP_FORMAT", msg.prerelease({ currentVersion }));
|
|
29
29
|
}
|
package/dist/core/messages.js
CHANGED
|
@@ -36,7 +36,7 @@ function serverStart({
|
|
|
36
36
|
host,
|
|
37
37
|
base
|
|
38
38
|
}) {
|
|
39
|
-
const version = "4.6.
|
|
39
|
+
const version = "4.6.3";
|
|
40
40
|
const localPrefix = `${dim("\u2503")} Local `;
|
|
41
41
|
const networkPrefix = `${dim("\u2503")} Network `;
|
|
42
42
|
const emptyPrefix = " ".repeat(11);
|
|
@@ -261,7 +261,7 @@ function printHelp({
|
|
|
261
261
|
message.push(
|
|
262
262
|
linebreak(),
|
|
263
263
|
` ${bgGreen(black(` ${commandName} `))} ${green(
|
|
264
|
-
`v${"4.6.
|
|
264
|
+
`v${"4.6.3"}`
|
|
265
265
|
)} ${headline}`
|
|
266
266
|
);
|
|
267
267
|
}
|
|
@@ -33,7 +33,16 @@ export declare class RenderContext {
|
|
|
33
33
|
render(componentInstance: ComponentInstance | undefined): Promise<Response>;
|
|
34
34
|
createAPIContext(props: APIContext['props']): APIContext;
|
|
35
35
|
createResult(mod: ComponentInstance): Promise<SSRResult>;
|
|
36
|
-
|
|
36
|
+
/**
|
|
37
|
+
* The Astro global is sourced in 3 different phases:
|
|
38
|
+
* - **Static**: `.generator` and `.glob` is printed by the compiler, instantiated once per process per astro file
|
|
39
|
+
* - **Page-level**: `.request`, `.cookies`, `.locals` etc. These remain the same for the duration of the request.
|
|
40
|
+
* - **Component-level**: `.props`, `.slots`, and `.self` are unique to each _use_ of each component.
|
|
41
|
+
*
|
|
42
|
+
* The page level partial is used as the prototype of the user-visible `Astro` global object, which is instantiated once per use of a component.
|
|
43
|
+
*/
|
|
44
|
+
createAstro(result: SSRResult, astroStaticPartial: AstroGlobalPartial, props: Record<string, any>, slotValues: Record<string, any> | null): AstroGlobal;
|
|
45
|
+
createAstroPagePartial(result: SSRResult, astroStaticPartial: AstroGlobalPartial): Omit<AstroGlobal, 'props' | 'self' | 'slots'>;
|
|
37
46
|
clientAddress(): string;
|
|
38
47
|
computeCurrentLocale(): string | undefined;
|
|
39
48
|
computePreferredLocale(): string | undefined;
|
|
@@ -202,7 +202,41 @@ class RenderContext {
|
|
|
202
202
|
};
|
|
203
203
|
return result;
|
|
204
204
|
}
|
|
205
|
-
|
|
205
|
+
#astroPagePartial;
|
|
206
|
+
/**
|
|
207
|
+
* The Astro global is sourced in 3 different phases:
|
|
208
|
+
* - **Static**: `.generator` and `.glob` is printed by the compiler, instantiated once per process per astro file
|
|
209
|
+
* - **Page-level**: `.request`, `.cookies`, `.locals` etc. These remain the same for the duration of the request.
|
|
210
|
+
* - **Component-level**: `.props`, `.slots`, and `.self` are unique to each _use_ of each component.
|
|
211
|
+
*
|
|
212
|
+
* The page level partial is used as the prototype of the user-visible `Astro` global object, which is instantiated once per use of a component.
|
|
213
|
+
*/
|
|
214
|
+
createAstro(result, astroStaticPartial, props, slotValues) {
|
|
215
|
+
const astroPagePartial = this.#astroPagePartial ??= this.createAstroPagePartial(
|
|
216
|
+
result,
|
|
217
|
+
astroStaticPartial
|
|
218
|
+
);
|
|
219
|
+
const astroComponentPartial = { props, self: null };
|
|
220
|
+
const Astro = Object.assign(
|
|
221
|
+
Object.create(astroPagePartial),
|
|
222
|
+
astroComponentPartial
|
|
223
|
+
);
|
|
224
|
+
let _slots;
|
|
225
|
+
Object.defineProperty(Astro, "slots", {
|
|
226
|
+
get: () => {
|
|
227
|
+
if (!_slots) {
|
|
228
|
+
_slots = new Slots(
|
|
229
|
+
result,
|
|
230
|
+
slotValues,
|
|
231
|
+
this.pipeline.logger
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
return _slots;
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
return Astro;
|
|
238
|
+
}
|
|
239
|
+
createAstroPagePartial(result, astroStaticPartial) {
|
|
206
240
|
const renderContext = this;
|
|
207
241
|
const { cookies, locals, params, pipeline, request, url } = this;
|
|
208
242
|
const { response } = result;
|
|
@@ -214,10 +248,9 @@ class RenderContext {
|
|
|
214
248
|
}
|
|
215
249
|
return new Response(null, { status, headers: { Location: path } });
|
|
216
250
|
};
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
glob: astroGlobalPartial.glob,
|
|
251
|
+
return {
|
|
252
|
+
generator: astroStaticPartial.generator,
|
|
253
|
+
glob: astroStaticPartial.glob,
|
|
221
254
|
cookies,
|
|
222
255
|
get clientAddress() {
|
|
223
256
|
return renderContext.clientAddress();
|
|
@@ -232,16 +265,13 @@ class RenderContext {
|
|
|
232
265
|
get preferredLocaleList() {
|
|
233
266
|
return renderContext.computePreferredLocaleList();
|
|
234
267
|
},
|
|
235
|
-
props,
|
|
236
268
|
locals,
|
|
237
269
|
redirect,
|
|
238
270
|
request,
|
|
239
271
|
response,
|
|
240
|
-
slots,
|
|
241
272
|
site: pipeline.site,
|
|
242
273
|
url
|
|
243
274
|
};
|
|
244
|
-
return astroGlobalCombined;
|
|
245
275
|
}
|
|
246
276
|
clientAddress() {
|
|
247
277
|
const { pipeline, request } = this;
|
|
@@ -57,7 +57,8 @@ type RunHookBuildDone = {
|
|
|
57
57
|
pages: string[];
|
|
58
58
|
routes: RouteData[];
|
|
59
59
|
logging: Logger;
|
|
60
|
+
cacheManifest: boolean;
|
|
60
61
|
};
|
|
61
|
-
export declare function runHookBuildDone({ config, pages, routes, logging }: RunHookBuildDone): Promise<void>;
|
|
62
|
+
export declare function runHookBuildDone({ config, pages, routes, logging, cacheManifest, }: RunHookBuildDone): Promise<void>;
|
|
62
63
|
export declare function isFunctionPerRouteEnabled(adapter: AstroAdapter | undefined): boolean;
|
|
63
64
|
export {};
|
|
@@ -349,7 +349,13 @@ async function runHookBuildGenerated({
|
|
|
349
349
|
}
|
|
350
350
|
}
|
|
351
351
|
}
|
|
352
|
-
async function runHookBuildDone({
|
|
352
|
+
async function runHookBuildDone({
|
|
353
|
+
config,
|
|
354
|
+
pages,
|
|
355
|
+
routes,
|
|
356
|
+
logging,
|
|
357
|
+
cacheManifest
|
|
358
|
+
}) {
|
|
353
359
|
const dir = isServerLikeOutput(config) ? config.build.client : config.outDir;
|
|
354
360
|
await fs.promises.mkdir(dir, { recursive: true });
|
|
355
361
|
for (const integration of config.integrations) {
|
|
@@ -362,7 +368,8 @@ async function runHookBuildDone({ config, pages, routes, logging }) {
|
|
|
362
368
|
pages: pages.map((p) => ({ pathname: p })),
|
|
363
369
|
dir,
|
|
364
370
|
routes,
|
|
365
|
-
logger
|
|
371
|
+
logger,
|
|
372
|
+
cacheManifest
|
|
366
373
|
}),
|
|
367
374
|
logger: logging
|
|
368
375
|
});
|
|
@@ -177,7 +177,9 @@ var settings_default = {
|
|
|
177
177
|
if (placement === settings.config[setting.settingKey]) {
|
|
178
178
|
option.selected = true;
|
|
179
179
|
}
|
|
180
|
-
option.textContent = `${placement.slice(0, 1).toUpperCase()}${placement.slice(
|
|
180
|
+
option.textContent = `${placement.slice(0, 1).toUpperCase()}${placement.slice(
|
|
181
|
+
1
|
|
182
|
+
)}`.replace("-", " ");
|
|
181
183
|
astroSelect.append(option);
|
|
182
184
|
});
|
|
183
185
|
astroSelect.element.addEventListener("change", setting.changeEvent);
|
|
@@ -248,7 +248,9 @@ class AstroDevToolbar extends HTMLElement {
|
|
|
248
248
|
this.apps.find((app) => app.builtIn && app.id === "astro:more")
|
|
249
249
|
) : ""}
|
|
250
250
|
<div class="separator"></div>
|
|
251
|
-
${this.getAppTemplate(
|
|
251
|
+
${this.getAppTemplate(
|
|
252
|
+
this.apps.find((app) => app.builtIn && app.id === "astro:settings")
|
|
253
|
+
)}
|
|
252
254
|
</div>
|
|
253
255
|
</div>
|
|
254
256
|
<div id="dev-bar-hitbox-below"></div>
|
|
@@ -16,6 +16,9 @@ async function renderToString(result, componentFactory, props, children, isPage
|
|
|
16
16
|
return templateResult;
|
|
17
17
|
let str = "";
|
|
18
18
|
let renderedFirstPageChunk = false;
|
|
19
|
+
if (isPage) {
|
|
20
|
+
await bufferHeadContent(result);
|
|
21
|
+
}
|
|
19
22
|
const destination = {
|
|
20
23
|
write(chunk) {
|
|
21
24
|
if (isPage && !renderedFirstPageChunk) {
|
|
@@ -203,8 +203,10 @@ async function updateDOM(preparationEvent, options, historyState, fallback) {
|
|
|
203
203
|
if (activeElement) {
|
|
204
204
|
activeElement.focus();
|
|
205
205
|
if (activeElement instanceof HTMLInputElement || activeElement instanceof HTMLTextAreaElement) {
|
|
206
|
-
|
|
207
|
-
|
|
206
|
+
if (typeof start === "number")
|
|
207
|
+
activeElement.selectionStart = start;
|
|
208
|
+
if (typeof end === "number")
|
|
209
|
+
activeElement.selectionEnd = end;
|
|
208
210
|
}
|
|
209
211
|
}
|
|
210
212
|
};
|
|
@@ -267,6 +269,7 @@ async function updateDOM(preparationEvent, options, historyState, fallback) {
|
|
|
267
269
|
return style.animationIterationCount === "infinite";
|
|
268
270
|
}
|
|
269
271
|
const currentAnimations = document.getAnimations();
|
|
272
|
+
await new Promise((r) => setTimeout(r));
|
|
270
273
|
document.documentElement.setAttribute(OLD_NEW_ATTR, phase);
|
|
271
274
|
const nextAnimations = document.getAnimations();
|
|
272
275
|
const newAnimations = nextAnimations.filter(
|
|
@@ -54,10 +54,17 @@ function astro({ settings, logger }) {
|
|
|
54
54
|
}
|
|
55
55
|
const filename = normalizePath(normalizeFilename(parsedId.filename, config.root));
|
|
56
56
|
let compileMetadata = astroFileToCompileMetadata.get(filename);
|
|
57
|
-
if (!compileMetadata
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
if (!compileMetadata) {
|
|
58
|
+
if (server) {
|
|
59
|
+
const code = await loadId(server.pluginContainer, filename);
|
|
60
|
+
if (code != null)
|
|
61
|
+
await compile(code, filename);
|
|
62
|
+
} else if (config.experimental.contentCollectionCache) {
|
|
63
|
+
await this.load({
|
|
64
|
+
id: filename,
|
|
65
|
+
resolveDependencies: false
|
|
66
|
+
});
|
|
67
|
+
}
|
|
61
68
|
compileMetadata = astroFileToCompileMetadata.get(filename);
|
|
62
69
|
}
|
|
63
70
|
if (!compileMetadata) {
|
|
@@ -39,6 +39,11 @@ function markdown({ settings, logger }) {
|
|
|
39
39
|
const rawFile = await fs.promises.readFile(fileId, "utf-8");
|
|
40
40
|
const raw = safeParseFrontmatter(rawFile, id);
|
|
41
41
|
const fileURL = pathToFileURL(fileId);
|
|
42
|
+
if (!processor) {
|
|
43
|
+
return this.error(
|
|
44
|
+
"MDX processor is not initialized. This is an internal error. Please file an issue."
|
|
45
|
+
);
|
|
46
|
+
}
|
|
42
47
|
const renderResult = await processor.render(raw.content, {
|
|
43
48
|
// @ts-expect-error passing internal prop
|
|
44
49
|
fileURL,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro",
|
|
3
|
-
"version": "4.6.
|
|
3
|
+
"version": "4.6.3",
|
|
4
4
|
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "withastro",
|
|
@@ -110,6 +110,7 @@
|
|
|
110
110
|
"@babel/traverse": "^7.23.3",
|
|
111
111
|
"@babel/types": "^7.23.3",
|
|
112
112
|
"@types/babel__core": "^7.20.4",
|
|
113
|
+
"@types/cookie": "^0.5.4",
|
|
113
114
|
"acorn": "^8.11.2",
|
|
114
115
|
"aria-query": "^5.3.0",
|
|
115
116
|
"axobject-query": "^4.0.0",
|
|
@@ -177,7 +178,6 @@
|
|
|
177
178
|
"@types/chai": "^4.3.10",
|
|
178
179
|
"@types/common-ancestor-path": "^1.0.2",
|
|
179
180
|
"@types/connect": "^3.4.38",
|
|
180
|
-
"@types/cookie": "^0.5.4",
|
|
181
181
|
"@types/cssesc": "^3.0.2",
|
|
182
182
|
"@types/debug": "^4.1.12",
|
|
183
183
|
"@types/diff": "^5.0.8",
|