Socket
Book a DemoSign in
Socket

astro

Package Overview
Dependencies
Maintainers
2
Versions
1309
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

astro - npm Package Compare versions

Comparing version
6.0.3
to
6.0.4
+1
-1
dist/cli/infra/build-time-astro-version-provider.js
class BuildTimeAstroVersionProvider {
// Injected during the build through esbuild define
version = "6.0.3";
version = "6.0.4";
}

@@ -5,0 +5,0 @@ export {

@@ -192,3 +192,3 @@ import { existsSync, promises as fs } from "node:fs";

}
if (previousAstroVersion && previousAstroVersion !== "6.0.3") {
if (previousAstroVersion && previousAstroVersion !== "6.0.4") {
logger.info("Astro version changed");

@@ -201,4 +201,4 @@ shouldClear = true;

}
if ("6.0.3") {
this.#store.metaStore().set("astro-version", "6.0.3");
if ("6.0.4") {
this.#store.metaStore().set("astro-version", "6.0.4");
}

@@ -205,0 +205,0 @@ if (currentConfigDigest) {

@@ -1,2 +0,4 @@

import type { AstroInlineConfig } from '../../types/public/config.js';
import type { AstroSettings, RoutesList } from '../../types/astro.js';
import type { AstroInlineConfig, RuntimeMode } from '../../types/public/config.js';
import type { Logger } from '../logger/core.js';
interface BuildOptions {

@@ -28,2 +30,38 @@ /**

export default function build(inlineConfig: AstroInlineConfig, options?: BuildOptions): Promise<void>;
interface AstroBuilderOptions extends BuildOptions {
logger: Logger;
mode: string;
runtimeMode: RuntimeMode;
/**
* Provide a pre-built routes list to skip filesystem route scanning.
* Useful for testing builds with in-memory virtual modules.
*/
routesList?: RoutesList;
/**
* Whether to run `syncInternal` during setup. Defaults to true.
* Set to false for in-memory builds that don't need type generation.
*/
sync?: boolean;
}
export declare class AstroBuilder {
private settings;
private logger;
private mode;
private runtimeMode;
private origin;
private routesList;
private timer;
private teardownCompiler;
private sync;
constructor(settings: AstroSettings, options: AstroBuilderOptions);
/** Setup Vite and run any async setup logic that couldn't run inside of the constructor. */
private setup;
/** Run the build logic. build() is marked private because usage should go through ".run()" */
private build;
/** Build the given Astro project. */
run(): Promise<void>;
private validateConfig;
/** Stats */
private printStats;
}
export {};

@@ -59,2 +59,3 @@ import fs from "node:fs";

teardownCompiler;
sync;
constructor(settings, options) {

@@ -66,4 +67,5 @@ this.mode = options.mode;

this.teardownCompiler = options.teardownCompiler ?? true;
this.sync = options.sync ?? true;
this.origin = settings.config.site ? new URL(settings.config.site).origin : `http://localhost:${settings.config.server.port}`;
this.routesList = { routes: [] };
this.routesList = options.routesList ?? { routes: [] };
this.timer = {};

@@ -82,3 +84,5 @@ }

this.settings.buildOutput = getPrerenderDefault(this.settings.config) ? "static" : "server";
this.routesList = await createRoutesList({ settings: this.settings }, this.logger);
if (this.routesList.routes.length === 0) {
this.routesList = await createRoutesList({ settings: this.settings }, this.logger);
}
await runHookConfigDone({ settings: this.settings, logger, command: "build" });

@@ -104,10 +108,12 @@ if (!this.settings.config.adapter && this.settings.buildOutput === "server") {

);
const { syncInternal } = await import("../sync/index.js");
await syncInternal({
mode: this.mode,
settings: this.settings,
logger,
fs,
command: "build"
});
if (this.sync) {
const { syncInternal } = await import("../sync/index.js");
await syncInternal({
mode: this.mode,
settings: this.settings,
logger,
fs,
command: "build"
});
}
return { viteConfig };

@@ -222,3 +228,4 @@ }

export {
AstroBuilder,
build as default
};

@@ -13,3 +13,7 @@ import fs from "node:fs";

import { SERIALIZED_MANIFEST_RESOLVED_ID } from "../../manifest/serialized.js";
import { getClientOutputDirectory, getServerOutputDirectory } from "../../prerender/utils.js";
import {
getClientOutputDirectory,
getPrerenderOutputDirectory,
getServerOutputDirectory
} from "../../prerender/utils.js";
import { VIRTUAL_PAGE_RESOLVED_MODULE_ID } from "../../vite-plugin-pages/const.js";

@@ -34,2 +38,3 @@ import { PAGE_SCRIPT_ID } from "../../vite-plugin-scripts/index.js";

import { getSSRAssets } from "./internal.js";
import { serverIslandPlaceholderMap } from "../server-islands/vite-plugin-server-islands.js";
const PRERENDER_ENTRY_FILENAME_PREFIX = "prerender-entry";

@@ -43,3 +48,4 @@ function extractRelevantChunks(outputs, prerender) {

const needsManifestInjection = chunk.moduleIds.includes(SERIALIZED_MANIFEST_RESOLVED_ID);
if (needsContentInjection || needsManifestInjection) {
const needsServerIslandInjection = chunk.code.includes(serverIslandPlaceholderMap);
if (needsContentInjection || needsManifestInjection || needsServerIslandInjection) {
extracted.push({

@@ -88,2 +94,3 @@ fileName: chunk.fileName,

let currentRollupInput = void 0;
let buildPostHooks = [];
plugins.push({

@@ -114,4 +121,9 @@ name: "astro:resolve-input",

async handler() {
await runManifestInjection(opts, internals, internals.extractedChunks ?? []);
const prerenderOutputDir = new URL("./.prerender/", getServerOutputDirectory(settings));
await runManifestInjection(
opts,
internals,
internals.extractedChunks ?? [],
buildPostHooks
);
const prerenderOutputDir = getPrerenderOutputDirectory(settings);
if (settings.buildOutput === "static") {

@@ -232,2 +244,6 @@ settings.timer.start("Static generate");

prerenderOutput = void 0;
const ssrPlugins = builder2.environments[ASTRO_VITE_ENVIRONMENT_NAMES.ssr]?.config.plugins ?? [];
buildPostHooks = ssrPlugins.map(
(plugin) => typeof plugin.api?.buildPostHook === "function" ? plugin.api.buildPostHook : void 0
).filter(Boolean);
internals.clientInput = getClientInput(internals, settings);

@@ -253,3 +269,3 @@ if (!internals.clientInput.size) {

emitAssets: true,
outDir: fileURLToPath(new URL("./.prerender/", getServerOutputDirectory(settings))),
outDir: fileURLToPath(getPrerenderOutputDirectory(settings)),
rollupOptions: {

@@ -328,3 +344,3 @@ // Only skip the default prerender entrypoint if an adapter with `entrypointResolution: 'self'` is used

}
async function runManifestInjection(opts, internals, chunks) {
async function runManifestInjection(opts, internals, chunks, buildPostHooks) {
const mutations = /* @__PURE__ */ new Map();

@@ -341,2 +357,5 @@ const mutate = (fileName, newCode, prerender) => {

);
for (const buildPostHook of buildPostHooks) {
await buildPostHook({ chunks, mutate });
}
await writeMutatedChunks(opts, mutations);

@@ -347,7 +366,6 @@ }

const config = settings.config;
const serverOutputDir = getServerOutputDirectory(settings);
for (const [fileName, mutation] of mutations) {
let root;
if (mutation.prerender) {
root = new URL("./.prerender/", serverOutputDir);
root = getPrerenderOutputDirectory(settings);
} else if (settings.buildOutput === "server") {

@@ -354,0 +372,0 @@ root = config.build.server;

@@ -1,2 +0,2 @@

const ASTRO_VERSION = "6.0.3";
const ASTRO_VERSION = "6.0.4";
const ASTRO_GENERATOR = `Astro v${ASTRO_VERSION}`;

@@ -3,0 +3,0 @@ const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute";

@@ -29,3 +29,3 @@ import fs from "node:fs";

const logger = restart.container.logger;
const currentVersion = "6.0.3";
const currentVersion = "6.0.4";
const isPrerelease = currentVersion.includes("-");

@@ -32,0 +32,0 @@ if (!isPrerelease) {

@@ -93,3 +93,3 @@ import * as fs from "node:fs";

if (/Unknown file extension "\.(?:jsx|vue|svelte|astro|css)" for /.test(err.message)) {
return "You likely need to add this package to `vite.ssr.noExternal` in your astro config file.";
return "You likely need to add this package to `vite.resolve.noExternal` in your astro config file.";
} else if (commonBrowserAPIs.some((api) => err.toString().includes(api))) {

@@ -96,0 +96,0 @@ const hint = `Browser APIs are not available on the server.

@@ -272,3 +272,3 @@ import colors from "piccolore";

` ${bgGreen(black(` ${commandName} `))} ${green(
`v${"6.0.3"}`
`v${"6.0.4"}`
)} ${headline}`

@@ -275,0 +275,0 @@ );

import type { Plugin as VitePlugin } from 'vite';
import type { AstroPluginOptions } from '../../types/astro.js';
export declare const SERVER_ISLAND_MANIFEST = "virtual:astro:server-island-manifest";
export declare const serverIslandPlaceholderMap = "'$$server-islands-map$$'";
export declare function vitePluginServerIslands({ settings }: AstroPluginOptions): VitePlugin;

@@ -1,3 +0,5 @@

import MagicString from "magic-string";
import fs from "node:fs";
import { getPrerenderOutputDirectory, getServerOutputDirectory } from "../../prerender/utils.js";
import { AstroError, AstroErrorData } from "../errors/index.js";
import { appendForwardSlash } from "../path.js";
import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../constants.js";

@@ -8,2 +10,14 @@ const SERVER_ISLAND_MANIFEST = "virtual:astro:server-island-manifest";

const serverIslandPlaceholderNameMap = "'$$server-islands-name-map$$'";
function createServerIslandImportMapSource(entries, toImportPath) {
const mappings = Array.from(entries, ([islandName, fileName]) => {
const importPath = toImportPath(fileName);
return ` [${JSON.stringify(islandName)}, () => import(${JSON.stringify(importPath)})],`;
});
return `new Map([
${mappings.join("\n")}
])`;
}
function createNameMapSource(entries) {
return `new Map(${JSON.stringify(Array.from(entries), null, 2)})`;
}
function vitePluginServerIslands({ settings }) {

@@ -15,2 +29,4 @@ let command = "serve";

const serverIslandNameMap = /* @__PURE__ */ new Map();
const resolvedIslandImports = /* @__PURE__ */ new Map();
let ssrManifestChunk = null;
return {

@@ -75,3 +91,3 @@ name: "astro:server-islands",

if (command === "build") {
let referenceId = this.emitFile({
const referenceId = this.emitFile({
type: "chunk",

@@ -101,8 +117,7 @@ id: comp.specifier,

if (serverIslandNameMap.size > 0 && serverIslandMap.size > 0) {
let mapSource = "new Map([\n ";
for (let [name, path] of serverIslandMap) {
mapSource += `
['${name}', () => import('${path}')],`;
}
mapSource += "]);";
const mapSource = createServerIslandImportMapSource(
serverIslandMap,
(fileName) => fileName
);
const nameMapSource = createNameMapSource(serverIslandNameMap);
return {

@@ -113,3 +128,3 @@ code: `

export const serverIslandNameMap = new Map(${JSON.stringify(Array.from(serverIslandNameMap.entries()), null, 2)});
export const serverIslandNameMap = ${nameMapSource};
`

@@ -123,30 +138,107 @@ };

if (code.includes(serverIslandPlaceholderMap)) {
if (referenceIdMap.size === 0) {
if (command === "build") {
if (referenceIdMap.size === 0) {
return;
}
const isRelativeChunk = !chunk.isEntry;
const dots = isRelativeChunk ? ".." : ".";
const mapEntries = [];
for (const [resolvedPath, referenceId] of referenceIdMap) {
const fileName = this.getFileName(referenceId);
const islandName = serverIslandNameMap.get(resolvedPath);
if (!islandName) continue;
if (!resolvedIslandImports.has(islandName)) {
resolvedIslandImports.set(islandName, fileName);
}
mapEntries.push([islandName, fileName]);
}
const mapSource = createServerIslandImportMapSource(
mapEntries,
(fileName) => `${dots}/${fileName}`
);
const nameMapSource = createNameMapSource(serverIslandNameMap);
return {
code: code.replace(serverIslandPlaceholderMap, "new Map();").replace(serverIslandPlaceholderNameMap, "new Map()"),
code: code.replace(serverIslandPlaceholderMap, mapSource).replace(serverIslandPlaceholderNameMap, nameMapSource),
map: null
};
}
const isRelativeChunk = !chunk.isEntry;
const dots = isRelativeChunk ? ".." : ".";
let mapSource = "new Map([";
let nameMapSource = "new Map(";
for (let [resolvedPath, referenceId] of referenceIdMap) {
const fileName = this.getFileName(referenceId);
const islandName = serverIslandNameMap.get(resolvedPath);
mapSource += `
['${islandName}', () => import('${dots}/${fileName}')],`;
}
nameMapSource += `${JSON.stringify(Array.from(serverIslandNameMap.entries()), null, 2)}`;
mapSource += "\n])";
nameMapSource += "\n)";
referenceIdMap.clear();
const ms = new MagicString(code);
ms.replace(serverIslandPlaceholderMap, mapSource);
ms.replace(serverIslandPlaceholderNameMap, nameMapSource);
return {
code: ms.toString(),
map: ms.generateMap({ hires: "boundary" })
code: code.replace(serverIslandPlaceholderMap, "new Map();").replace(serverIslandPlaceholderNameMap, "new Map()"),
map: null
};
}
},
generateBundle(_options, bundle) {
const envName = this.environment?.name;
if (envName === ASTRO_VITE_ENVIRONMENT_NAMES.ssr) {
for (const chunk of Object.values(bundle)) {
if (chunk.type === "chunk" && chunk.code.includes(serverIslandPlaceholderMap)) {
ssrManifestChunk = chunk;
break;
}
}
}
if (envName === ASTRO_VITE_ENVIRONMENT_NAMES.prerender && ssrManifestChunk) {
if (resolvedIslandImports.size > 0) {
const isRelativeChunk = ssrManifestChunk.fileName.includes("/");
const dots = isRelativeChunk ? ".." : ".";
const mapSource = createServerIslandImportMapSource(
resolvedIslandImports,
(fileName) => `${dots}/${fileName}`
);
const nameMapSource = createNameMapSource(serverIslandNameMap);
ssrManifestChunk.code = ssrManifestChunk.code.replace(serverIslandPlaceholderMap, mapSource).replace(serverIslandPlaceholderNameMap, nameMapSource);
} else {
ssrManifestChunk.code = ssrManifestChunk.code.replace(serverIslandPlaceholderMap, "new Map()").replace(serverIslandPlaceholderNameMap, "new Map()");
}
}
},
api: {
/**
* Post-build hook that patches SSR chunks containing server island placeholders.
*
* During build, SSR can run before all server islands are discovered (e.g. islands
* only used in prerendered pages). This hook runs after SSR + prerender builds and:
* 1) replaces placeholders with the complete map of discovered islands
* 2) copies island chunks emitted in prerender into the SSR output directory
*
* Two cases:
* 1. Islands were discovered: Replace placeholders with real import maps.
* 2. No islands found: Replace placeholders with empty maps.
*/
async buildPostHook({
chunks,
mutate
}) {
const ssrChunkWithPlaceholder = chunks.find(
(c) => !c.prerender && c.code.includes(serverIslandPlaceholderMap)
);
if (!ssrChunkWithPlaceholder) {
return;
}
if (resolvedIslandImports.size > 0) {
const isRelativeChunk = ssrChunkWithPlaceholder.fileName.includes("/");
const dots = isRelativeChunk ? ".." : ".";
const mapSource = createServerIslandImportMapSource(
resolvedIslandImports,
(fileName) => `${dots}/${fileName}`
);
const nameMapSource = createNameMapSource(serverIslandNameMap);
const newCode = ssrChunkWithPlaceholder.code.replace(serverIslandPlaceholderMap, mapSource).replace(serverIslandPlaceholderNameMap, nameMapSource);
mutate(ssrChunkWithPlaceholder.fileName, newCode, false);
const serverOutputDir = getServerOutputDirectory(settings);
const prerenderOutputDir = getPrerenderOutputDirectory(settings);
for (const [, fileName] of resolvedIslandImports) {
const srcPath = new URL(fileName, appendForwardSlash(prerenderOutputDir.toString()));
const destPath = new URL(fileName, appendForwardSlash(serverOutputDir.toString()));
if (!fs.existsSync(srcPath)) continue;
const destDir = new URL("./", destPath);
await fs.promises.mkdir(destDir, { recursive: true });
await fs.promises.copyFile(srcPath, destPath);
}
} else {
const newCode = ssrChunkWithPlaceholder.code.replace(serverIslandPlaceholderMap, "new Map()").replace(serverIslandPlaceholderNameMap, "new Map()");
mutate(ssrChunkWithPlaceholder.fileName, newCode, false);
}
}
}

@@ -157,3 +249,4 @@ };

SERVER_ISLAND_MANIFEST,
serverIslandPlaceholderMap,
vitePluginServerIslands
};

@@ -77,5 +77,6 @@ import { removeTrailingForwardSlash } from "@astrojs/internal-helpers/path";

if (isRoot) {
const basePrefix = this.#base === "/" ? "" : this.#base;
return {
type: "redirect",
location: `${this.#base}/${this.#defaultLocale}`
location: `${basePrefix}/${this.#defaultLocale}`
};

@@ -82,0 +83,0 @@ }

@@ -9,4 +9,8 @@ import type { AstroSettings } from '../types/astro.js';

/**
* Returns the output directory used by the prerender environment.
*/
export declare function getPrerenderOutputDirectory(settings: AstroSettings): URL;
/**
* Returns the correct output directory of the client build based on the configuration
*/
export declare function getClientOutputDirectory(settings: AstroSettings): URL;

@@ -8,2 +8,5 @@ import { getOutDirWithinCwd } from "../core/build/common.js";

}
function getPrerenderOutputDirectory(settings) {
return new URL("./.prerender/", getServerOutputDirectory(settings));
}
function getClientOutputDirectory(settings) {

@@ -19,3 +22,4 @@ const preserveStructure = settings.adapter?.adapterFeatures?.preserveBuildClientDir;

getPrerenderDefault,
getPrerenderOutputDirectory,
getServerOutputDirectory
};

@@ -13,3 +13,7 @@ import { telemetry } from "../events/index.js";

// Optimize CJS dependencies used by the dev toolbar
include: ["astro > aria-query", "astro > axobject-query"]
include: [
"astro > aria-query",
"astro > axobject-query",
...settings.devToolbarApps.length > 0 ? ["astro/toolbar"] : []
]
}

@@ -16,0 +20,0 @@ };

@@ -45,5 +45,9 @@ import * as fs from "node:fs";

const rootFilePath = new URL("." + pathname, config.root);
if (fs.existsSync(rootFilePath)) {
const html = notFoundTemplate(pathname);
return writeHtmlResponse(res, 404, html);
try {
const stat = fs.statSync(rootFilePath);
if (stat.isFile()) {
const html = notFoundTemplate(pathname);
return writeHtmlResponse(res, 404, html);
}
} catch {
}

@@ -50,0 +54,0 @@ return next();

@@ -65,3 +65,3 @@ import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../core/constants.js";

],
exclude: ["astro:*", "virtual:astro:*"],
exclude: ["astro:*", "virtual:astro:*", "astro/virtual-modules/prefetch.js"],
// Astro files can't be rendered on the client

@@ -68,0 +68,0 @@ entries: [`${srcDirPattern}**/*.{jsx,tsx,vue,svelte,html}`]

@@ -14,2 +14,3 @@ import { extname } from "node:path";

import { isAstroServerEnvironment } from "../environments.js";
import { RESOLVED_MODULE_DEV_CSS_ALL } from "../vite-plugin-css/const.js";
import { PAGE_SCRIPT_ID } from "../vite-plugin-scripts/index.js";

@@ -95,2 +96,6 @@ const ASTRO_ROUTES_MODULE_ID = "virtual:astro:routes";

environment.moduleGraph.invalidateModule(virtualMod);
const cssMod = environment.moduleGraph.getModuleById(RESOLVED_MODULE_DEV_CSS_ALL);
if (cssMod) {
environment.moduleGraph.invalidateModule(cssMod);
}
environment.hot.send("astro:routes-updated", {});

@@ -97,0 +102,0 @@ }

{
"name": "astro",
"version": "6.0.3",
"version": "6.0.4",
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",

@@ -156,5 +156,5 @@ "type": "module",

"zod": "^4.3.6",
"@astrojs/internal-helpers": "0.8.0",
"@astrojs/markdown-remark": "7.0.0",
"@astrojs/telemetry": "3.3.0",
"@astrojs/internal-helpers": "0.8.0"
"@astrojs/telemetry": "3.3.0"
},

@@ -161,0 +161,0 @@ "optionalDependencies": {

@@ -1,2 +0,1 @@

/* eslint-disable @typescript-eslint/no-unused-vars */
// @ts-check

@@ -3,0 +2,0 @@ import { schema } from 'virtual:astro:env/internal';