Release v2.8.0
- #495 by @bobsingor – Added support for reading and writing Caret annotations (
PdfCaretAnnoObject). Added support for reading and writing Rectangle Differences (/RD) for annotations that support it.
- #495 by @bobsingor – Added
PdfCaretAnnoObjectdefinition for Caret annotations. AddedPdfRectDifferencesinterface andrectangleDifferencesproperty toPdfCircleAnnoObject,PdfSquareAnnoObject,PdfPolygonAnnoObject,PdfFreeTextAnnoObject, andPdfCaretAnnoObjectto support the PDF/RDentry.
- #495 by @bobsingor – Exposed
EPDFAnnot_SetRectangleDifferences,EPDFAnnot_ClearRectangleDifferences, andEPDFAnnot_HasAppearanceStreamfunctions.
-
#510 by @bobsingor – Fix redact annotations leaving orphan indirect objects in the PDF cross-reference table.
EPDFAnnot_ApplyRedactionandEPDFPage_ApplyRedactionsnow callDeleteIndirectObjectafter removing each annotation from the/Annotsarray, ensuring the underlying PDF object is fully removed from the xref rather than left as an unreachable orphan.Thanks to @JanSlabon for reporting this bug.
-
#509 by @bobsingor – Implement noZoom and noRotate annotation flag rendering. Annotations with noZoom now maintain a constant screen-pixel size regardless of zoom level, and annotations with noRotate stay visually upright regardless of page rotation.
-
#495 by @bobsingor – Added "Insert Text" and "Replace Text" annotation tools. Added renderer for Caret annotations. Added support for grouped annotations in selectors (e.g. for Replace Text where a Caret and Strikeout are grouped).
-
#509 by @bobsingor – Add Text (comment) annotation tool with handler, tool definition, and renderer support. thanks to @JoackimPennerup
-
#502 by @danielbayerlein – Add dashed stroke support to Polyline component for React, Vue and Svelte frameworks. Thanks @danielbayerlein!
-
#495 by @bobsingor – Fix markup annotations (highlight, underline, strikethrough) not being created on PDFs that lack
CopyContentspermission. Annotations are now created without extracted text metadata when text extraction is denied. -
#495 by @bobsingor – Add
isRotatable: falseto text markup annotation tools (highlight, underline, strikeout, squiggly) to explicitly prevent rotation on these text-anchored annotations. -
#495 by @bobsingor – Fix marquee selection selecting non-rendered annotation types (e.g. POPUP, TEXT, WIDGET). Only annotations with a visual renderer are now included in marquee selection results.
-
#508 by @bobsingor – Fix newly created annotations showing their appearance stream instead of dict-based rendering. New annotations now consistently start with
dictMode: trueacross all framework wrappers (React, Vue, Svelte). -
#509 by @bobsingor – Fix group selection box outline when selected annotations use
noZoomand/ornoRotateflags. The multi-select group outline now correctly encloses mixed selections (flagged + normal annotations), including rotated pages and non-square noRotate annotations. -
#495 by @bobsingor – Remove redundant
onTouchStarthandlers from annotation renderers.onPointerDownalready covers touch input on all modern browsers, so the duplicate handler caused non-passive event listener violations and double-fired on touch devices.
-
#495 by @bobsingor – Added UI controls and commands for "Insert Text" and "Replace Text" tools. Added support for rendering Caret annotations and grouped annotations (like Replace Text) in the comment sidebar.
-
#509 by @bobsingor – Add comment annotation toolbar button with message icon, command, and UI schema entry.
- #495 by @bobsingor – Fix markup annotation commands (highlight, underline, strikeout, squiggly) not creating annotations on PDFs that lack
CopyContentspermission. Annotations are now created without extracted text metadata when text extraction is denied.
- #495 by @bobsingor – Remove redundant
onTouchStarthandlers from redaction renderers.onPointerDownalready covers touch input on all modern browsers, so the duplicate handler caused non-passive event listener violations and double-fired on touch devices.
-
#504 by @danielbayerlein – Support shift-key to temporarily lock aspect ratio during resize across all framework adapters (React, Preact, Vue, Svelte). Thanks to @danielbayerlein
-
#495 by @bobsingor – Mark
touchstartlistener inCounterRotateContaineras passive to eliminate Chrome scroll-blocking violation.
@astrojs/internal-helpers@0.8.0-beta.3
- #15778
4ebc1e3Thanks @ematipico! - Added a new entry point called/request, which exposes utilities to work with theRequesttype:getFirstForwardedValue: retrieves the first value of a multi-value header.isValidIpAddress: checks whether a string contains only characters valid in IPv4/IPv6 addresses.getValidatedIpFromHeader: extracts the first value from a header and validates it as an IP address.getClientIpAddress: retrieves and validates the first IP from thex-forwarded-forheader.
astro@6.0.0-beta.20
- #15424
33d6146Thanks @Princesseuh! - Throws an error whengetImage()fromastro:assetsis called on the client - (v6 upgrade guidance)
-
#15700
4e7f3e8Thanks @ocavue! - Updates the internal logic during SSR by providing additional metadata for UI framework integrations. -
#15781
2de969dThanks @ematipico! - Adds a newclientAddressoption to thecreateContext()functionProviding this value gives adapter and middleware authors explicit control over the client IP address. When not provided, accessing
clientAddressthrows an error consistent with other contexts where it is not set by the adapter.Additionally, both of the official Netlify and Vercel adapters have been updated to provide this information in their edge middleware.
import { createContext } from 'astro/middleware'; createContext({ clientAddress: context.headers.get('x-real-ip'), });
-
#15755
f9ee868Thanks @matthewp! - Adds a newsecurity.serverIslandBodySizeLimitconfiguration optionServer island POST endpoints now enforce a body size limit, similar to the existing
security.actionBodySizeLimitfor Actions. The new option defaults to1048576(1 MB) and can be configured independently.Requests exceeding the limit are rejected with a 413 response. You can customize the limit in your Astro config:
export default defineConfig({ security: { serverIslandBodySizeLimit: 2097152, // 2 MB }, });
-
#15712
7ac43c7Thanks @florian-lefebvre! - Improvesastro infoby supporting more operating systems when copying the information to the clipboard. -
#15780
e0ac125Thanks @ematipico! - Preventsvite.envPrefixmisconfiguration from exposingaccess: "secret"environment variables in client-side bundles. Astro now throws a clear error at startup if anyvite.envPrefixentry matches a variable declared withaccess: "secret"inenv.schema.For example, the following configuration will throw an error for
API_SECRETbecause it's defined assecretits name matches['PUBLIC_', 'API_']defined inenv.schema:// astro.config.mjs import { defineConfig } from 'astro/config'; export default defineConfig({ env: { schema: { API_SECRET: envField.string({ context: 'server', access: 'secret', optional: true }), API_URL: envField.string({ context: 'server', access: 'public', optional: true }), }, }, vite: { envPrefix: ['PUBLIC_', 'API_'], }, });
-
#15778
4ebc1e3Thanks @ematipico! - Fixes an issue where the computedclientAddresswas incorrect in cases of a Request header with multiple values. TheclientAddressis now also validated to contain only characters valid in IP addresses, rejecting injection payloads. -
#15776
e9a9cc6Thanks @matthewp! - Hardens error page response merging to ensure framing headers from the original response are not carried over to the rendered error page -
#15759
39ff2a5Thanks @matthewp! - Adds a newbodySizeLimitoption to the@astrojs/nodeadapterYou can now configure a maximum allowed request body size for your Node.js standalone server. The default limit is 1 GB. Set the value in bytes, or pass
0to disable the limit entirely:import node from '@astrojs/node'; import { defineConfig } from 'astro/config'; export default defineConfig({ adapter: node({ mode: 'standalone', bodySizeLimit: 1024 * 1024 * 100, // 100 MB }), });
-
#15777
02e24d9Thanks @matthewp! - Fixes CSRF origin check mismatch by passing the actual server listening port tocreateRequest, ensuring the constructed URL origin includes the correct port (e.g.,http://localhost:4321instead ofhttp://localhost). Also restrictsX-Forwarded-Prototo only be trusted whenallowedDomainsis configured. -
#15768
6328f1aThanks @matthewp! - Hardens internal cookie parsing to use a null-prototype object consistently for the fallback path, aligning with how the cookie library handles parsed values -
#15757
631aaedThanks @matthewp! - Hardens URL pathname normalization to consistently handle backslash characters after decoding, ensuring middleware and router see the same canonical pathname -
#15761
8939751Thanks @ematipico! - Fixes an issue where it wasn't possible to setexperimental.queuedRendering.poolSizeto0. -
#15764
44daecfThanks @matthewp! - Fixes form actions incorrectly auto-executing during error page rendering. When an error page (e.g. 404) is rendered, form actions from the original request are no longer executed, since the full request handling pipeline is not active. -
#15788
a91da9fThanks @florian-lefebvre! - Reverts changes made to TSConfig templates -
Updated dependencies [
4ebc1e3,4e7f3e8]:- @astrojs/internal-helpers@0.8.0-beta.3
- @astrojs/markdown-remark@7.0.0-beta.11
@astrojs/node@10.0.0-beta.9
-
#15759
39ff2a5Thanks @matthewp! - Adds a newbodySizeLimitoption to the@astrojs/nodeadapterYou can now configure a maximum allowed request body size for your Node.js standalone server. The default limit is 1 GB. Set the value in bytes, or pass
0to disable the limit entirely:import node from '@astrojs/node'; import { defineConfig } from 'astro/config'; export default defineConfig({ adapter: node({ mode: 'standalone', bodySizeLimit: 1024 * 1024 * 100, // 100 MB }), });
-
#15777
02e24d9Thanks @matthewp! - Fixes CSRF origin check mismatch by passing the actual server listening port tocreateRequest, ensuring the constructed URL origin includes the correct port (e.g.,http://localhost:4321instead ofhttp://localhost). Also restrictsX-Forwarded-Prototo only be trusted whenallowedDomainsis configured. -
#15763
1567e8cThanks @matthewp! - Normalizes static file paths before evaluating dotfile access rules for improved consistency -
Updated dependencies [
4ebc1e3,4e7f3e8]:- @astrojs/internal-helpers@0.8.0-beta.3
@astrojs/netlify@7.0.0-beta.14
-
#15781
2de969dThanks @ematipico! - Adds a newclientAddressoption to thecreateContext()functionProviding this value gives adapter and middleware authors explicit control over the client IP address. When not provided, accessing
clientAddressthrows an error consistent with other contexts where it is not set by the adapter.Additionally, both of the official Netlify and Vercel adapters have been updated to provide this information in their edge middleware.
import { createContext } from 'astro/middleware'; createContext({ clientAddress: context.headers.get('x-real-ip'), });
-
Updated dependencies [
4ebc1e3,4e7f3e8]:- @astrojs/internal-helpers@0.8.0-beta.3
- @astrojs/underscore-redirects@1.0.0
@astrojs/vercel@10.0.0-beta.8
-
#15781
2de969dThanks @ematipico! - Adds a newclientAddressoption to thecreateContext()functionProviding this value gives adapter and middleware authors explicit control over the client IP address. When not provided, accessing
clientAddressthrows an error consistent with other contexts where it is not set by the adapter.Additionally, both of the official Netlify and Vercel adapters have been updated to provide this information in their edge middleware.
import { createContext } from 'astro/middleware'; createContext({ clientAddress: context.headers.get('x-real-ip'), });
-
#15778
4ebc1e3Thanks @ematipico! - Fixes an issue where the computedclientAddresswas incorrect in cases of a Request header with multiple values. TheclientAddressis now also validated to contain only characters valid in IP addresses, rejecting injection payloads. -
Updated dependencies [
4ebc1e3,4e7f3e8]:- @astrojs/internal-helpers@0.8.0-beta.3