diff --git a/packages/astro/src/assets/utils/vendor/image-size/README.md b/packages/astro/src/assets/utils/vendor/image-size/README.md index b1b6a1ec7797..21345cd83dac 100644 --- a/packages/astro/src/assets/utils/vendor/image-size/README.md +++ b/packages/astro/src/assets/utils/vendor/image-size/README.md @@ -7,3 +7,4 @@ Vendored from [image-size](https://github.com/image-size/image-size) v2.0.2. - Files removed: `fromFile.ts`, `index.ts` - Added `avis` brand for AVIF sequences (`./types/heif.ts`) - Added `detectType()` to handle files with out-of-order ftyp brands (`./types/heif.ts`) +- Updates `BitReader` properties assignment to work with `erasableSyntaxOnly` diff --git a/packages/astro/src/assets/utils/vendor/image-size/utils/bit-reader.ts b/packages/astro/src/assets/utils/vendor/image-size/utils/bit-reader.ts index cbe4f1a1b78b..f5fd246d4032 100644 --- a/packages/astro/src/assets/utils/vendor/image-size/utils/bit-reader.ts +++ b/packages/astro/src/assets/utils/vendor/image-size/utils/bit-reader.ts @@ -3,11 +3,16 @@ export class BitReader { // Skip the first 16 bits (2 bytes) of signature private byteOffset = 2 private bitOffset = 0 + private readonly input: Uint8Array + private readonly endianness: 'big-endian' | 'little-endian' constructor( - private readonly input: Uint8Array, - private readonly endianness: 'big-endian' | 'little-endian', - ) {} + input: Uint8Array, + endianness: 'big-endian' | 'little-endian', + ) { + this.input = input + this.endianness = endianness + } /** Reads a specified number of bits, and move the offset */ getBits(length = 1): number { diff --git a/packages/astro/src/cli/add/index.ts b/packages/astro/src/cli/add/index.ts index b1e2b27f3383..060b96627762 100644 --- a/packages/astro/src/cli/add/index.ts +++ b/packages/astro/src/cli/add/index.ts @@ -206,7 +206,7 @@ export async function add(names: string[], { flags }: AddOptions) { } switch (installResult) { - case UpdateResult.updated: { + case 'updated': { if (hasCloudflareIntegration) { const wranglerConfigURL = new URL('./wrangler.jsonc', configURL); if (!existsSync(wranglerConfigURL)) { @@ -371,7 +371,7 @@ export async function add(names: string[], { flags }: AddOptions) { } break; } - case UpdateResult.cancelled: { + case 'cancelled': { logger.info( 'SKIP_FORMAT', msg.cancelled( @@ -381,10 +381,10 @@ export async function add(names: string[], { flags }: AddOptions) { ); break; } - case UpdateResult.failure: { + case 'failure': { throw createPrettyError(new Error(`Unable to install dependencies`)); } - case UpdateResult.none: + case 'none': break; } @@ -448,14 +448,14 @@ export async function add(names: string[], { flags }: AddOptions) { } switch (configResult) { - case UpdateResult.cancelled: { + case 'cancelled': { logger.info( 'SKIP_FORMAT', msg.cancelled(`Your configuration has ${bold('NOT')} been updated.`), ); break; } - case UpdateResult.none: { + case 'none': { const data = await getPackageJson(); if (data) { const { dependencies = {}, devDependencies = {} } = data; @@ -473,9 +473,9 @@ export async function add(names: string[], { flags }: AddOptions) { break; } // NOTE: failure shouldn't happen in practice because `updateAstroConfig` doesn't return that. - // Pipe this to the same handling as `UpdateResult.updated` for now. - case UpdateResult.failure: - case UpdateResult.updated: + // Pipe this to the same handling as `'updated'` for now. + case 'failure': + case 'updated': case undefined: { const list = integrations .map((integration) => ` - ${integration.integrationName}`) @@ -513,22 +513,22 @@ export async function add(names: string[], { flags }: AddOptions) { }); switch (updateTSConfigResult) { - case UpdateResult.none: { + case 'none': { break; } - case UpdateResult.cancelled: { + case 'cancelled': { logger.info( 'SKIP_FORMAT', msg.cancelled(`Your TypeScript configuration has ${bold('NOT')} been updated.`), ); break; } - case UpdateResult.failure: { + case 'failure': { throw new Error( `Unknown error parsing tsconfig.json or jsconfig.json. Could not update TypeScript settings.`, ); } - case UpdateResult.updated: + case 'updated': logger.info('SKIP_FORMAT', msg.success(`Successfully updated tsconfig`)); } } @@ -652,12 +652,7 @@ function setAdapter(mod: ProxifiedModule, adapter: IntegrationInfo, exportN } } -const enum UpdateResult { - none, - updated, - cancelled, - failure, -} +type UpdateResult = 'none' | 'updated' | 'cancelled' | 'failure'; async function updateAstroConfig({ configURL, @@ -682,13 +677,13 @@ async function updateAstroConfig({ }).code; if (input === output) { - return UpdateResult.none; + return 'none'; } const diff = getDiffContent(input, output); if (!diff) { - return UpdateResult.none; + return 'none'; } logger.info( @@ -716,9 +711,9 @@ async function updateAstroConfig({ if (await askToContinue({ flags, logger })) { await fs.writeFile(fileURLToPath(configURL), output, { encoding: 'utf-8' }); logger.debug('add', `Updated astro config`); - return UpdateResult.updated; + return 'updated'; } else { - return UpdateResult.cancelled; + return 'cancelled'; } } @@ -736,7 +731,7 @@ async function updatePackageJsonOverrides({ const pkgURL = new URL('./package.json', configURL); if (!existsSync(pkgURL)) { logger.debug('add', 'No package.json found, skipping overrides update'); - return UpdateResult.none; + return 'none'; } const pkgPath = fileURLToPath(pkgURL); @@ -753,14 +748,14 @@ async function updatePackageJsonOverrides({ } if (!hasChanges) { - return UpdateResult.none; + return 'none'; } const output = JSON.stringify(pkgJson, null, 2); const diff = getDiffContent(input, output); if (!diff) { - return UpdateResult.none; + return 'none'; } logger.info( @@ -777,9 +772,9 @@ async function updatePackageJsonOverrides({ if (await askToContinue({ flags, logger })) { await fs.writeFile(pkgPath, output, { encoding: 'utf-8' }); logger.debug('add', 'Updated package.json overrides'); - return UpdateResult.updated; + return 'updated'; } else { - return UpdateResult.cancelled; + return 'cancelled'; } } @@ -797,7 +792,7 @@ async function updatePackageJsonScripts({ const pkgURL = new URL('./package.json', configURL); if (!existsSync(pkgURL)) { logger.debug('add', 'No package.json found, skipping scripts update'); - return UpdateResult.none; + return 'none'; } const pkgPath = fileURLToPath(pkgURL); @@ -814,14 +809,14 @@ async function updatePackageJsonScripts({ } if (!hasChanges) { - return UpdateResult.none; + return 'none'; } const output = JSON.stringify(pkgJson, null, 2); const diff = getDiffContent(input, output); if (!diff) { - return UpdateResult.none; + return 'none'; } logger.info( @@ -838,9 +833,9 @@ async function updatePackageJsonScripts({ if (await askToContinue({ flags, logger })) { await fs.writeFile(pkgPath, output, { encoding: 'utf-8' }); logger.debug('add', 'Updated package.json scripts'); - return UpdateResult.updated; + return 'updated'; } else { - return UpdateResult.cancelled; + return 'cancelled'; } } @@ -903,7 +898,7 @@ async function tryToInstallIntegrations({ strategies: ['install-metadata', 'lockfile', 'packageManager-field'], }); logger.debug('add', `package manager: "${packageManager?.name}"`); - if (!packageManager) return UpdateResult.none; + if (!packageManager) return 'none'; const inheritedFlags = Object.entries(flags) .map(([flag]) => { @@ -917,7 +912,7 @@ async function tryToInstallIntegrations({ .flat() as string[]; const installCommand = resolveCommand(packageManager?.agent ?? 'npm', 'add', inheritedFlags); - if (!installCommand) return UpdateResult.none; + if (!installCommand) return 'none'; const installSpecifiers = await convertIntegrationsToInstallSpecifiers(integrations).then( (specifiers) => @@ -951,16 +946,16 @@ async function tryToInstallIntegrations({ }, }); spinner.stop('Dependencies installed.'); - return UpdateResult.updated; + return 'updated'; } catch (err: any) { spinner.error('Error installing dependencies.'); logger.debug('add', 'Error installing dependencies', err); // NOTE: `err.stdout` can be an empty string, so log the full error instead for a more helpful log console.error('\n', err.stdout || err.message, '\n'); - return UpdateResult.failure; + return 'failure'; } } else { - return UpdateResult.cancelled; + return 'cancelled'; } } @@ -1100,14 +1095,14 @@ async function updateTSConfig( ); if (!firstIntegrationWithTSSettings && includesToAppend.length === 0) { - return UpdateResult.none; + return 'none'; } let inputConfig = await loadTSConfig(cwd); let inputConfigText = ''; if (inputConfig === 'invalid-config' || inputConfig === 'unknown-error') { - return UpdateResult.failure; + return 'failure'; } else if (inputConfig === 'missing-config') { logger.debug('add', "Couldn't find tsconfig.json or jsconfig.json, generating one"); inputConfig = { @@ -1136,7 +1131,7 @@ async function updateTSConfig( const diff = getDiffContent(inputConfigText, output); if (!diff) { - return UpdateResult.none; + return 'none'; } logger.info( @@ -1181,9 +1176,9 @@ async function updateTSConfig( encoding: 'utf-8', }); logger.debug('add', `Updated ${configFileName} file`); - return UpdateResult.updated; + return 'updated'; } else { - return UpdateResult.cancelled; + return 'cancelled'; } } diff --git a/packages/astro/src/content/loaders/errors.ts b/packages/astro/src/content/loaders/errors.ts index 00020554736e..52215a2511ae 100644 --- a/packages/astro/src/content/loaders/errors.ts +++ b/packages/astro/src/content/loaders/errors.ts @@ -5,12 +5,15 @@ function formatZodError(error: z.$ZodError): string[] { } export class LiveCollectionError extends Error { - constructor( - public readonly collection: string, - public readonly message: string, - public readonly cause?: Error, - ) { + public readonly collection: string; + public readonly message: string; + public readonly cause?: Error; + + constructor(collection: string, message: string, cause?: Error) { super(message); + this.collection = collection; + this.message = message; + this.cause = cause; this.name = 'LiveCollectionError'; if (cause?.stack) { this.stack = cause.stack; diff --git a/packages/astro/src/core/base-pipeline.ts b/packages/astro/src/core/base-pipeline.ts index be941c2568ce..02a128cb08e9 100644 --- a/packages/astro/src/core/base-pipeline.ts +++ b/packages/astro/src/core/base-pipeline.ts @@ -22,7 +22,7 @@ import { NOOP_MIDDLEWARE_FN } from './middleware/noop-middleware.js'; import { sequence } from './middleware/sequence.js'; import { RedirectSinglePageBuiltModule } from './redirects/index.js'; import { RouteCache } from './render/route-cache.js'; -import { createDefaultRoutes } from './routing/default.js'; +import { createDefaultRoutes, type DefaultRouteParams } from './routing/default.js'; import type { CacheProvider, CacheProviderFactory } from './cache/types.js'; import type { CompiledCacheRoute } from './cache/runtime/route-matching.js'; import type { SessionDriverFactory } from './session/types.js'; @@ -45,43 +45,100 @@ export abstract class Pipeline { nodePool: NodePool | undefined; htmlStringCache: HTMLStringCache | undefined; + readonly logger: Logger; + readonly manifest: SSRManifest; + /** + * "development" or "production" only + */ + readonly runtimeMode: RuntimeMode; + readonly renderers: SSRLoadedRenderer[]; + readonly resolve: (s: string) => Promise; + + readonly streaming: boolean; + /** + * Used to provide better error messages for `Astro.clientAddress` + */ + readonly adapterName: SSRManifest['adapterName']; + readonly clientDirectives: SSRManifest['clientDirectives']; + readonly inlinedScripts: SSRManifest['inlinedScripts']; + readonly compressHTML: SSRManifest['compressHTML']; + readonly i18n: SSRManifest['i18n']; + readonly middleware: SSRManifest['middleware']; + readonly routeCache: RouteCache; + /** + * Used for `Astro.site`. + */ + readonly site: URL | undefined; + /** + * Array of built-in, internal, routes. + * Used to find the route module + */ + readonly defaultRoutes: Array; + + readonly actions: SSRManifest['actions']; + readonly sessionDriver: SSRManifest['sessionDriver']; + readonly cacheProvider: SSRManifest['cacheProvider']; + readonly cacheConfig: SSRManifest['cacheConfig']; + readonly serverIslands: SSRManifest['serverIslandMappings']; + constructor( - readonly logger: Logger, - readonly manifest: SSRManifest, + logger: Logger, + manifest: SSRManifest, /** * "development" or "production" only */ - readonly runtimeMode: RuntimeMode, - readonly renderers: SSRLoadedRenderer[], - readonly resolve: (s: string) => Promise, + runtimeMode: RuntimeMode, + renderers: SSRLoadedRenderer[], + resolve: (s: string) => Promise, - readonly streaming: boolean, + streaming: boolean, /** * Used to provide better error messages for `Astro.clientAddress` */ - readonly adapterName = manifest.adapterName, - readonly clientDirectives = manifest.clientDirectives, - readonly inlinedScripts = manifest.inlinedScripts, - readonly compressHTML = manifest.compressHTML, - readonly i18n = manifest.i18n, - readonly middleware = manifest.middleware, - readonly routeCache = new RouteCache(logger, runtimeMode), + adapterName = manifest.adapterName, + clientDirectives = manifest.clientDirectives, + inlinedScripts = manifest.inlinedScripts, + compressHTML = manifest.compressHTML, + i18n = manifest.i18n, + middleware = manifest.middleware, + routeCache = new RouteCache(logger, runtimeMode), /** * Used for `Astro.site`. */ - readonly site = manifest.site ? new URL(manifest.site) : undefined, + site = manifest.site ? new URL(manifest.site) : undefined, /** * Array of built-in, internal, routes. * Used to find the route module */ - readonly defaultRoutes = createDefaultRoutes(manifest), + defaultRoutes = createDefaultRoutes(manifest), - readonly actions = manifest.actions, - readonly sessionDriver = manifest.sessionDriver, - readonly cacheProvider = manifest.cacheProvider, - readonly cacheConfig = manifest.cacheConfig, - readonly serverIslands = manifest.serverIslandMappings, + actions = manifest.actions, + sessionDriver = manifest.sessionDriver, + cacheProvider = manifest.cacheProvider, + cacheConfig = manifest.cacheConfig, + serverIslands = manifest.serverIslandMappings, ) { + this.logger = logger; + this.manifest = manifest; + this.runtimeMode = runtimeMode; + this.renderers = renderers; + this.resolve = resolve; + this.streaming = streaming; + this.adapterName = adapterName; + this.clientDirectives = clientDirectives; + this.inlinedScripts = inlinedScripts; + this.compressHTML = compressHTML; + this.i18n = i18n; + this.middleware = middleware; + this.routeCache = routeCache; + this.site = site; + this.defaultRoutes = defaultRoutes; + this.actions = actions; + this.sessionDriver = sessionDriver; + this.cacheProvider = cacheProvider; + this.cacheConfig = cacheConfig; + this.serverIslands = serverIslands; + this.internalMiddleware = []; // We do use our middleware only if the user isn't using the manual setup if (i18n?.strategy !== 'manual') { diff --git a/packages/astro/src/core/build/pipeline.ts b/packages/astro/src/core/build/pipeline.ts index c94cc31e69cb..21ece179a594 100644 --- a/packages/astro/src/core/build/pipeline.ts +++ b/packages/astro/src/core/build/pipeline.ts @@ -10,7 +10,7 @@ import type { TryRewriteResult } from '../base-pipeline.js'; import { RedirectSinglePageBuiltModule } from '../redirects/component.js'; import { Pipeline } from '../base-pipeline.js'; import { createAssetLink, createStylesheetElementSet } from '../render/ssr-element.js'; -import { createDefaultRoutes } from '../routing/default.js'; +import { createDefaultRoutes, type DefaultRouteParams } from '../routing/default.js'; import { getFallbackRoute, routeIsFallback, routeIsRedirect } from '../routing/helpers.js'; import { findRouteToRewrite } from '../routing/rewrite.js'; import type { BuildInternals } from './internal.js'; @@ -26,6 +26,8 @@ import { queueRenderingEnabled } from '../app/manifest.js'; export class BuildPipeline extends Pipeline { internals: BuildInternals | undefined; options: StaticBuildOptions | undefined; + readonly manifest: SSRManifest; + readonly defaultRoutes: Array; getName(): string { return 'BuildPipeline'; @@ -58,10 +60,7 @@ export class BuildPipeline extends Pipeline { return this.internals; } - private constructor( - readonly manifest: SSRManifest, - readonly defaultRoutes = createDefaultRoutes(manifest), - ) { + private constructor(manifest: SSRManifest, defaultRoutes = createDefaultRoutes(manifest)) { const resolveCache = new Map(); async function resolve(specifier: string) { @@ -85,6 +84,8 @@ export class BuildPipeline extends Pipeline { const logger = createConsoleLogger(manifest.logLevel); // We can skip streaming in SSG for performance as writing as strings are faster super(logger, manifest, 'production', manifest.renderers, resolve, manifest.serverLike); + this.manifest = manifest; + this.defaultRoutes = defaultRoutes; if (queueRenderingEnabled(this.manifest.experimentalQueuedRendering)) { this.nodePool = newNodePool(this.manifest.experimentalQueuedRendering!); if (this.manifest.experimentalQueuedRendering!.contentCache) { diff --git a/packages/astro/src/core/cookies/cookies.ts b/packages/astro/src/core/cookies/cookies.ts index 5ec231f56aa1..b4c982786ef0 100644 --- a/packages/astro/src/core/cookies/cookies.ts +++ b/packages/astro/src/core/cookies/cookies.ts @@ -46,7 +46,10 @@ const responseSentSymbol = Symbol.for('astro.responseSent'); const identity = (value: string) => value; class AstroCookie implements AstroCookieInterface { - constructor(public value: string) {} + public value: string; + constructor(value: string) { + this.value = value; + } json() { if (this.value === undefined) { throw new Error(`Cannot convert undefined to an object.`); diff --git a/packages/astro/src/core/render-context.ts b/packages/astro/src/core/render-context.ts index fba5014e5bdf..3ce124e61374 100644 --- a/packages/astro/src/core/render-context.ts +++ b/packages/astro/src/core/render-context.ts @@ -12,7 +12,7 @@ import { import { renderEndpoint } from '../runtime/server/endpoint.js'; import { renderPage } from '../runtime/server/index.js'; import type { ComponentInstance } from '../types/astro.js'; -import type { MiddlewareHandler, Props, RewritePayload } from '../types/public/common.js'; +import type { MiddlewareHandler, Params, Props, RewritePayload } from '../types/public/common.js'; import type { APIContext, AstroGlobal } from '../types/public/context.js'; import type { RouteData, SSRResult } from '../types/public/internal.js'; import type { ServerIslandMappings, SSRActions } from './app/types.js'; @@ -67,28 +67,69 @@ export type CreateRenderContext = Pick< >; export class RenderContext { + readonly pipeline: Pipeline; + public locals: App.Locals; + readonly middleware: MiddlewareHandler; + readonly actions: SSRActions; + readonly serverIslands: ServerIslandMappings; + // It must be a DECODED pathname + public pathname: string; + public request: Request; + public routeData: RouteData; + public status: number; + public clientAddress: string | undefined; + protected cookies: AstroCookies; + public params: Params; + protected url: URL; + public props: Props; + public partial: undefined | boolean; + public shouldInjectCspMetaTags: boolean; + public session: AstroSession | undefined; + public cache: CacheLike; + public skipMiddleware: boolean; + private constructor( - readonly pipeline: Pipeline, - public locals: App.Locals, - readonly middleware: MiddlewareHandler, - readonly actions: SSRActions, - readonly serverIslands: ServerIslandMappings, + pipeline: Pipeline, + locals: App.Locals, + middleware: MiddlewareHandler, + actions: SSRActions, + serverIslands: ServerIslandMappings, // It must be a DECODED pathname - public pathname: string, - public request: Request, - public routeData: RouteData, - public status: number, - public clientAddress: string | undefined, - protected cookies = new AstroCookies(request), - public params = getParams(routeData, pathname), - protected url = RenderContext.#createNormalizedUrl(request.url), - public props: Props = {}, - public partial: undefined | boolean = undefined, - public shouldInjectCspMetaTags = pipeline.manifest.shouldInjectCspMetaTags, - public session: AstroSession | undefined = undefined, - public cache: CacheLike, - public skipMiddleware = false, - ) {} + pathname: string, + request: Request, + routeData: RouteData, + status: number, + clientAddress: string | undefined, + cookies = new AstroCookies(request), + params = getParams(routeData, pathname), + url = RenderContext.#createNormalizedUrl(request.url), + props: Props = {}, + partial: undefined | boolean = undefined, + shouldInjectCspMetaTags = pipeline.manifest.shouldInjectCspMetaTags, + session: AstroSession | undefined = undefined, + cache: CacheLike, + skipMiddleware = false, + ) { + this.pipeline = pipeline; + this.locals = locals; + this.middleware = middleware; + this.actions = actions; + this.serverIslands = serverIslands; + this.pathname = pathname; + this.request = request; + this.routeData = routeData; + this.status = status; + this.clientAddress = clientAddress; + this.cookies = cookies; + this.params = params; + this.url = url; + this.props = props; + this.partial = partial; + this.shouldInjectCspMetaTags = shouldInjectCspMetaTags; + this.session = session; + this.cache = cache; + this.skipMiddleware = skipMiddleware; + } static #createNormalizedUrl(requestUrl: string): URL { const url = new URL(requestUrl); diff --git a/packages/astro/src/core/routing/default.ts b/packages/astro/src/core/routing/default.ts index 1793231a4f53..2dddd7fd1186 100644 --- a/packages/astro/src/core/routing/default.ts +++ b/packages/astro/src/core/routing/default.ts @@ -8,12 +8,12 @@ import { } from '../server-islands/endpoint.js'; import { DEFAULT_404_ROUTE, default404Instance } from './internal/astro-designed-error-pages.js'; -type DefaultRouteParams = { +export interface DefaultRouteParams { instance: ComponentInstance; matchesComponent(filePath: URL): boolean; route: string; component: string; -}; +} export const DEFAULT_COMPONENTS = [DEFAULT_404_COMPONENT, SERVER_ISLAND_COMPONENT]; diff --git a/packages/astro/src/preferences/store.ts b/packages/astro/src/preferences/store.ts index 373ec88c165f..7243384b0155 100644 --- a/packages/astro/src/preferences/store.ts +++ b/packages/astro/src/preferences/store.ts @@ -5,12 +5,11 @@ import { dset } from 'dset'; import { SETTINGS_FILE } from './constants.js'; export class PreferenceStore { + private dir: string; private file: string; - constructor( - private dir: string, - filename = SETTINGS_FILE, - ) { + constructor(dir: string, filename = SETTINGS_FILE) { + this.dir = dir; this.file = path.join(this.dir, filename); } diff --git a/packages/astro/src/runtime/server/transition.ts b/packages/astro/src/runtime/server/transition.ts index da13a7b7d75e..cd730a9f866d 100644 --- a/packages/astro/src/runtime/server/transition.ts +++ b/packages/astro/src/runtime/server/transition.ts @@ -132,11 +132,13 @@ export function createAnimationScope( export class ViewTransitionStyleSheet { private modern: string[] = []; private fallback: string[] = []; + private scope: string; + private name: string; - constructor( - private scope: string, - private name: string, - ) {} + constructor(scope: string, name: string) { + this.scope = scope; + this.name = name; + } toString() { const { scope, name } = this; diff --git a/packages/astro/src/vite-plugin-app/pipeline.ts b/packages/astro/src/vite-plugin-app/pipeline.ts index 792a10b069a1..f26fbe6a167c 100644 --- a/packages/astro/src/vite-plugin-app/pipeline.ts +++ b/packages/astro/src/vite-plugin-app/pipeline.ts @@ -7,7 +7,7 @@ import type { Logger } from '../core/logger/core.js'; import type { ModuleLoader } from '../core/module-loader/index.js'; import { RedirectComponentInstance } from '../core/redirects/index.js'; import { loadRenderer } from '../core/render/index.js'; -import { createDefaultRoutes } from '../core/routing/default.js'; +import type { DefaultRouteParams } from '../core/routing/default.js'; import { routeIsRedirect } from '../core/routing/helpers.js'; import { findRouteToRewrite } from '../core/routing/rewrite.js'; import { isPage } from '../core/util.js'; @@ -46,17 +46,40 @@ export class RunnablePipeline extends Pipeline { routesList: RoutesList | undefined; + readonly loader: ModuleLoader; + readonly settings: AstroSettings; + readonly getDebugInfo: () => Promise; + private constructor( - readonly loader: ModuleLoader, - readonly logger: Logger, - readonly manifest: SSRManifest, - readonly settings: AstroSettings, - readonly getDebugInfo: () => Promise, - readonly defaultRoutes = createDefaultRoutes(manifest), + loader: ModuleLoader, + logger: Logger, + manifest: SSRManifest, + settings: AstroSettings, + getDebugInfo: () => Promise, + defaultRoutes?: Array, ) { const resolve = createResolve(loader, manifest.rootDir); const streaming = true; - super(logger, manifest, 'development', [], resolve, streaming); + super( + logger, + manifest, + 'development', + [], + resolve, + streaming, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + defaultRoutes, + ); + this.loader = loader; + this.settings = settings; + this.getDebugInfo = getDebugInfo; } static create( diff --git a/packages/astro/tsconfig.json b/packages/astro/tsconfig.json index b12a70b882d0..2eaf394f8501 100644 --- a/packages/astro/tsconfig.json +++ b/packages/astro/tsconfig.json @@ -7,6 +7,7 @@ "allowJs": true, "declarationDir": "./dist", "outDir": "./dist", - "jsx": "preserve" + "jsx": "preserve", + "erasableSyntaxOnly": true } } diff --git a/packages/integrations/vercel/src/index.ts b/packages/integrations/vercel/src/index.ts index c7672aacdf8c..bb7ae4eacc1d 100644 --- a/packages/integrations/vercel/src/index.ts +++ b/packages/integrations/vercel/src/index.ts @@ -651,16 +651,31 @@ type Runtime = `nodejs${string}.x`; class VercelBuilder { readonly NTF_CACHE = {}; + readonly config: AstroConfig; + readonly excludeFiles: URL[]; + readonly includeFiles: URL[]; + readonly logger: AstroIntegrationLogger; + readonly outDir: URL; + readonly maxDuration: number | undefined; + readonly runtime: string; constructor( - readonly config: AstroConfig, - readonly excludeFiles: URL[], - readonly includeFiles: URL[], - readonly logger: AstroIntegrationLogger, - readonly outDir: URL, - readonly maxDuration?: number, - readonly runtime = getRuntime(process, logger), - ) {} + config: AstroConfig, + excludeFiles: URL[], + includeFiles: URL[], + logger: AstroIntegrationLogger, + outDir: URL, + maxDuration?: number, + runtime = getRuntime(process, logger), + ) { + this.config = config; + this.excludeFiles = excludeFiles; + this.includeFiles = includeFiles; + this.logger = logger; + this.outDir = outDir; + this.maxDuration = maxDuration; + this.runtime = runtime; + } async buildServerlessFolder(entry: URL, functionName: string, root: URL) { const { includeFiles, excludeFiles, logger, NTF_CACHE, runtime, maxDuration } = this; diff --git a/packages/language-tools/language-server/src/check.ts b/packages/language-tools/language-server/src/check.ts index d49ac9f1c15c..245c4051e27c 100644 --- a/packages/language-tools/language-server/src/check.ts +++ b/packages/language-tools/language-server/src/check.ts @@ -33,12 +33,18 @@ export interface CheckResult { export class AstroCheck { private ts!: typeof import('typescript'); public linter!: ReturnType<(typeof kit)['createTypeScriptChecker']>; + private readonly workspacePath: string; + private readonly typescriptPath: string | undefined; + private readonly tsconfigPath: string | undefined; constructor( - private readonly workspacePath: string, - private readonly typescriptPath: string | undefined, - private readonly tsconfigPath: string | undefined, + workspacePath: string, + typescriptPath: string | undefined, + tsconfigPath: string | undefined, ) { + this.workspacePath = workspacePath; + this.typescriptPath = typescriptPath; + this.tsconfigPath = tsconfigPath; this.initialize(); } diff --git a/packages/language-tools/language-server/src/core/frontmatterHolders.ts b/packages/language-tools/language-server/src/core/frontmatterHolders.ts index aa627de1ec5e..66292c1e6cab 100644 --- a/packages/language-tools/language-server/src/core/frontmatterHolders.ts +++ b/packages/language-tools/language-server/src/core/frontmatterHolders.ts @@ -95,13 +95,21 @@ export class FrontmatterHolder implements VirtualCode { mappings: CodeMapping[]; embeddedCodes: VirtualCode[]; public hasFrontmatter = false; + public fileName: string; + public languageId: string; + public snapshot: ts.IScriptSnapshot; + public collection: string | undefined; constructor( - public fileName: string, - public languageId: string, - public snapshot: ts.IScriptSnapshot, - public collection: string | undefined, + fileName: string, + languageId: string, + snapshot: ts.IScriptSnapshot, + collection: string | undefined, ) { + this.fileName = fileName; + this.languageId = languageId; + this.snapshot = snapshot; + this.collection = collection; this.mappings = [ { sourceOffsets: [0], @@ -121,8 +129,8 @@ export class FrontmatterHolder implements VirtualCode { this.embeddedCodes = []; this.snapshot = snapshot; - // If the file is not part of a collection, we don't need to do anything if (!this.collection) { + // If the file is not part of a collection, we don't need to do anything return; } diff --git a/packages/language-tools/language-server/src/core/index.ts b/packages/language-tools/language-server/src/core/index.ts index b8ec8699de8a..0d1f18464113 100644 --- a/packages/language-tools/language-server/src/core/index.ts +++ b/packages/language-tools/language-server/src/core/index.ts @@ -149,11 +149,12 @@ export class AstroVirtualCode implements VirtualCode { compilerDiagnostics!: DiagnosticMessage[]; htmlDocument!: HTMLDocument; codegenStacks = []; + public fileName: string; + public snapshot: ts.IScriptSnapshot; - constructor( - public fileName: string, - public snapshot: ts.IScriptSnapshot, - ) { + constructor(fileName: string, snapshot: ts.IScriptSnapshot) { + this.fileName = fileName; + this.snapshot = snapshot; this.mappings = [ { sourceOffsets: [0], diff --git a/packages/language-tools/language-server/src/core/svelte.ts b/packages/language-tools/language-server/src/core/svelte.ts index 1418159a9adb..8d7275216bd2 100644 --- a/packages/language-tools/language-server/src/core/svelte.ts +++ b/packages/language-tools/language-server/src/core/svelte.ts @@ -45,11 +45,12 @@ class SvelteVirtualCode implements VirtualCode { mappings!: Mapping[]; embeddedCodes!: VirtualCode[]; codegenStacks = []; + public fileName: string; + public snapshot: ts.IScriptSnapshot; - constructor( - public fileName: string, - public snapshot: ts.IScriptSnapshot, - ) { + constructor(fileName: string, snapshot: ts.IScriptSnapshot) { + this.fileName = fileName; + this.snapshot = snapshot; this.mappings = []; this.embeddedCodes = []; diff --git a/packages/language-tools/language-server/src/core/vue.ts b/packages/language-tools/language-server/src/core/vue.ts index 3be6edc3e5c9..26beb97a8d52 100644 --- a/packages/language-tools/language-server/src/core/vue.ts +++ b/packages/language-tools/language-server/src/core/vue.ts @@ -45,11 +45,12 @@ class VueVirtualCode implements VirtualCode { mappings!: Mapping[]; embeddedCodes!: VirtualCode[]; codegenStacks = []; + public fileName: string; + public snapshot: ts.IScriptSnapshot; - constructor( - public fileName: string, - public snapshot: ts.IScriptSnapshot, - ) { + constructor(fileName: string, snapshot: ts.IScriptSnapshot) { + this.fileName = fileName; + this.snapshot = snapshot; this.mappings = []; this.embeddedCodes = []; diff --git a/packages/language-tools/ts-plugin/src/frontmatter.ts b/packages/language-tools/ts-plugin/src/frontmatter.ts index 215bfc1fc65b..4fdd5f7ffbde 100644 --- a/packages/language-tools/ts-plugin/src/frontmatter.ts +++ b/packages/language-tools/ts-plugin/src/frontmatter.ts @@ -87,13 +87,21 @@ export class FrontmatterHolder implements VirtualCode { id = 'frontmatter-holder'; mappings: CodeMapping[]; embeddedCodes: VirtualCode[]; + public fileName: string; + public languageId: string; + public snapshot: ts.IScriptSnapshot; + public collection: string | undefined; constructor( - public fileName: string, - public languageId: string, - public snapshot: ts.IScriptSnapshot, - public collection: string | undefined, + fileName: string, + languageId: string, + snapshot: ts.IScriptSnapshot, + collection: string | undefined, ) { + this.fileName = fileName; + this.languageId = languageId; + this.snapshot = snapshot; + this.collection = collection; this.mappings = [ { sourceOffsets: [0], diff --git a/packages/language-tools/ts-plugin/src/language.ts b/packages/language-tools/ts-plugin/src/language.ts index fc643e805980..6f5ba2cf0df7 100644 --- a/packages/language-tools/ts-plugin/src/language.ts +++ b/packages/language-tools/ts-plugin/src/language.ts @@ -44,11 +44,12 @@ export class AstroVirtualCode implements VirtualCode { mappings!: CodeMapping[]; embeddedCodes!: VirtualCode[]; codegenStacks = []; + public fileName: string; + public snapshot: ts.IScriptSnapshot; - constructor( - public fileName: string, - public snapshot: ts.IScriptSnapshot, - ) { + constructor(fileName: string, snapshot: ts.IScriptSnapshot) { + this.fileName = fileName; + this.snapshot = snapshot; this.mappings = [ { sourceOffsets: [0], diff --git a/packages/telemetry/src/config.ts b/packages/telemetry/src/config.ts index 359b1e11f86a..6ac6f06af17f 100644 --- a/packages/telemetry/src/config.ts +++ b/packages/telemetry/src/config.ts @@ -33,10 +33,12 @@ function getConfigDir(name: string) { } export class GlobalConfig { + private project: ConfigOptions; private dir: string; private file: string; - constructor(private project: ConfigOptions) { + constructor(project: ConfigOptions) { + this.project = project; this.dir = getConfigDir(this.project.name); this.file = path.join(this.dir, 'config.json'); } diff --git a/packages/telemetry/src/index.ts b/packages/telemetry/src/index.ts index c53bf4d73eaf..1941dc7652da 100644 --- a/packages/telemetry/src/index.ts +++ b/packages/telemetry/src/index.ts @@ -25,6 +25,7 @@ interface EventContext extends ProjectInfo { anonymousSessionId: string; } export class AstroTelemetry { + private opts: AstroTelemetryOptions; private _anonymousSessionId: string | undefined; private _anonymousProjectInfo: ProjectInfo | undefined; private config = new GlobalConfig({ name: 'astro' }); @@ -44,7 +45,8 @@ export class AstroTelemetry { return this.env.TELEMETRY_DISABLED; } - constructor(private opts: AstroTelemetryOptions) { + constructor(opts: AstroTelemetryOptions) { + this.opts = opts; // TODO: When the process exits, flush any queued promises // This caused a "cannot exist astro" error when it ran, so it was removed. // process.on('SIGINT', () => this.flush()); diff --git a/tsconfig.base.json b/tsconfig.base.json index 7ed082d83639..bb1f2630431b 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -13,6 +13,7 @@ "stripInternal": true, "noUnusedLocals": true, "noUnusedParameters": true, + "erasableSyntaxOnly": true, "types": ["node"] } }