From 2be25949eef415ceceb26c1a2ed6fb8e7fac81f1 Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Tue, 9 Dec 2025 15:26:53 -0700 Subject: [PATCH] tweaks --- packages/svelte/src/internal/server/renderer.js | 14 +++++++------- packages/svelte/src/internal/server/types.d.ts | 6 ++++-- packages/svelte/src/legacy/legacy-server.js | 13 +++++++------ packages/svelte/types/index.d.ts | 6 ++++-- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/packages/svelte/src/internal/server/renderer.js b/packages/svelte/src/internal/server/renderer.js index 856ece9dfd..6804f1b29b 100644 --- a/packages/svelte/src/internal/server/renderer.js +++ b/packages/svelte/src/internal/server/renderer.js @@ -1,5 +1,5 @@ /** @import { Component } from 'svelte' */ -/** @import { CspInternal, HydratableContext, RenderOutput, SSRContext, SyncRenderOutput } from './types.js' */ +/** @import { CspInternal, HydratableContext, RenderOutput, SSRContext, SyncRenderOutput, Sha256Source } from './types.js' */ /** @import { MaybePromise } from '#shared' */ import { async_mode_flag } from '../flags/index.js'; import { abort } from './abort-signal.js'; @@ -521,7 +521,7 @@ export class Renderer { * @template {Record} Props * @param {Component} component * @param {{ props?: Omit; context?: Map; idPrefix?: string; csp?: CspInternal }} options - * @returns {Promise} + * @returns {Promise} */ static async #render_async(component, options) { const previous_context = ssr_context; @@ -629,7 +629,7 @@ export class Renderer { /** * @param {AccumulatedContent} content * @param {Renderer} renderer - * @returns {AccumulatedContent & { hashes: { script: string[] } }} + * @returns {AccumulatedContent & { hashes: { script: Sha256Source[] } }} */ static #close_render(content, renderer) { for (const cleanup of renderer.#collect_on_destroy()) { @@ -706,7 +706,7 @@ export class Renderer { } export class SSRState { - /** @readonly @type {CspInternal & { script_hashes: string[] }} */ + /** @readonly @type {CspInternal & { script_hashes: Sha256Source[] }} */ csp; /** @readonly @type {'sync' | 'async'} */ @@ -723,10 +723,10 @@ export class SSRState { /** * @param {'sync' | 'async'} mode - * @param {string} [id_prefix] - * @param {CspInternal} [csp] + * @param {string} id_prefix + * @param {CspInternal} csp */ - constructor(mode, id_prefix = '', csp = { hash: false }) { + constructor(mode, id_prefix, csp = { hash: false }) { this.mode = mode; this.csp = { ...csp, script_hashes: [] }; diff --git a/packages/svelte/src/internal/server/types.d.ts b/packages/svelte/src/internal/server/types.d.ts index 7e768c85c0..23c985ad27 100644 --- a/packages/svelte/src/internal/server/types.d.ts +++ b/packages/svelte/src/internal/server/types.d.ts @@ -15,7 +15,7 @@ export interface SSRContext { element?: Element; } -export type Csp = { nonce: string } | { hash: true }; +export type Csp = { nonce: string } | { hash: boolean }; export type CspInternal = { nonce?: string; hash: boolean }; @@ -37,6 +37,8 @@ export interface RenderContext { hydratable: HydratableContext; } +export type Sha256Source = `sha256-${string}`; + export interface SyncRenderOutput { /** HTML that goes into the `` */ head: string; @@ -45,7 +47,7 @@ export interface SyncRenderOutput { /** HTML that goes somewhere into the `` */ body: string; hashes: { - script: string[]; + script: Sha256Source[]; }; } diff --git a/packages/svelte/src/legacy/legacy-server.js b/packages/svelte/src/legacy/legacy-server.js index a50d961751..05b329bea1 100644 --- a/packages/svelte/src/legacy/legacy-server.js +++ b/packages/svelte/src/legacy/legacy-server.js @@ -1,14 +1,14 @@ /** @import { SvelteComponent } from '../index.js' */ +/** @import { Csp } from '#server' */ import { asClassComponent as as_class_component, createClassComponent } from './legacy-client.js'; import { render } from '../internal/server/index.js'; import { async_mode_flag } from '../internal/flags/index.js'; -import * as w from '../internal/server/warnings.js'; // By having this as a separate entry point for server environments, we save the client bundle from having to include the server runtime export { createClassComponent }; -/** @typedef {{ head: string, html: string, css: { code: string, map: null }}} LegacyRenderResult */ +/** @typedef {{ head: string, html: string, css: { code: string, map: null }; hashes?: { script: `sha256-${string}`[] } }} LegacyRenderResult */ /** * Takes a Svelte 5 component and returns a Svelte 4 compatible component constructor. @@ -25,10 +25,10 @@ export { createClassComponent }; */ export function asClassComponent(component) { const component_constructor = as_class_component(component); - /** @type {(props?: {}, opts?: { $$slots?: {}; context?: Map; }) => LegacyRenderResult & PromiseLike } */ - const _render = (props, { context } = {}) => { + /** @type {(props?: {}, opts?: { $$slots?: {}; context?: Map; csp?: Csp }) => LegacyRenderResult & PromiseLike } */ + const _render = (props, { context, csp } = {}) => { // @ts-expect-error the typings are off, but this will work if the component is compiled in SSR mode - const result = render(component, { props, context }); + const result = render(component, { props, context, csp }); const munged = Object.defineProperties( /** @type {LegacyRenderResult & PromiseLike} */ ({}), @@ -65,7 +65,8 @@ export function asClassComponent(component) { return onfulfilled({ css: munged.css, head: result.head, - html: result.body + html: result.body, + hashes: result.hashes }); }, onrejected); } diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index 16fa2e6b0c..5b055ddb4f 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -2566,7 +2566,9 @@ declare module 'svelte/server' { } ] ): RenderOutput; - type Csp = { nonce: string } | { hash: true }; + type Csp = { nonce: string } | { hash: boolean }; + + type Sha256Source = `sha256-${string}`; interface SyncRenderOutput { /** HTML that goes into the `` */ @@ -2576,7 +2578,7 @@ declare module 'svelte/server' { /** HTML that goes somewhere into the `` */ body: string; hashes: { - script: string[]; + script: Sha256Source[]; }; }