From 0c3aad6560e45d4e2e79ebcbaa74f4781a6aae29 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Tue, 17 Jun 2025 12:32:28 -0600 Subject: [PATCH 01/74] feat: Initial tracing setup (peer deps + utils) --- packages/kit/package.json | 7 + .../kit/src/runtime/telemetry/get_tracer.js | 27 +++ .../src/runtime/telemetry/get_tracer.spec.js | 31 +++ .../kit/src/runtime/telemetry/load_otel.js | 18 ++ packages/kit/src/runtime/telemetry/noop.js | 81 +++++++ .../kit/src/runtime/telemetry/record_span.js | 75 +++++++ .../src/runtime/telemetry/record_span.spec.js | 198 ++++++++++++++++++ pnpm-lock.yaml | 9 + 8 files changed, 446 insertions(+) create mode 100644 packages/kit/src/runtime/telemetry/get_tracer.js create mode 100644 packages/kit/src/runtime/telemetry/get_tracer.spec.js create mode 100644 packages/kit/src/runtime/telemetry/load_otel.js create mode 100644 packages/kit/src/runtime/telemetry/noop.js create mode 100644 packages/kit/src/runtime/telemetry/record_span.js create mode 100644 packages/kit/src/runtime/telemetry/record_span.spec.js diff --git a/packages/kit/package.json b/packages/kit/package.json index 906b9735baeb..ed6031c481e1 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -32,6 +32,7 @@ "sirv": "^3.0.0" }, "devDependencies": { + "@opentelemetry/api": "^1.0.0", "@playwright/test": "catalog:", "@sveltejs/vite-plugin-svelte": "catalog:", "@types/connect": "^3.4.38", @@ -47,9 +48,15 @@ }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0", + "@opentelemetry/api": "^1.0.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0" }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + } + }, "bin": { "svelte-kit": "svelte-kit.js" }, diff --git a/packages/kit/src/runtime/telemetry/get_tracer.js b/packages/kit/src/runtime/telemetry/get_tracer.js new file mode 100644 index 000000000000..5c7fac29b412 --- /dev/null +++ b/packages/kit/src/runtime/telemetry/get_tracer.js @@ -0,0 +1,27 @@ +/** @import { Tracer } from '@opentelemetry/api' */ +import { DEV } from 'esm-env'; +import { noop_tracer } from './noop.js'; +import { load_otel } from './load_otel.js'; + +/** + * @param {Object} [options={}] - Configuration options + * @param {boolean} [options.is_enabled=false] - Whether tracing is enabled + * @returns {Promise} The tracer instance + */ +export async function get_tracer({ is_enabled = false } = {}) { + if (!is_enabled) { + return noop_tracer; + } + + const otel = await load_otel(); + if (otel === null) { + if (DEV) { + console.warn( + 'Tracing is enabled, but `@opentelemetry/api` is not available. Have you installed it?' + ); + } + return noop_tracer; + } + + return otel.tracer; +} diff --git a/packages/kit/src/runtime/telemetry/get_tracer.spec.js b/packages/kit/src/runtime/telemetry/get_tracer.spec.js new file mode 100644 index 000000000000..01a8dc74a9b1 --- /dev/null +++ b/packages/kit/src/runtime/telemetry/get_tracer.spec.js @@ -0,0 +1,31 @@ +import { describe, test, expect, beforeEach, vi } from 'vitest'; +import { get_tracer } from './get_tracer.js'; +import { noop_tracer } from './noop.js'; +import * as load_otel from './load_otel.js'; + +describe('get_tracer', () => { + beforeEach(() => { + vi.resetAllMocks(); + }); + + test('returns noop tracer if tracing is disabled', async () => { + const tracer = await get_tracer({ is_enabled: false }); + expect(tracer).toBe(noop_tracer); + }); + + test('returns noop tracer if @opentelemetry/api is not installed, warning', async () => { + vi.spyOn(load_otel, 'load_otel').mockResolvedValue(null); + const console_warn_spy = vi.spyOn(console, 'warn'); + + const tracer = await get_tracer({ is_enabled: true }); + expect(tracer).toBe(noop_tracer); + expect(console_warn_spy).toHaveBeenCalledWith( + 'Tracing is enabled, but `@opentelemetry/api` is not available. Have you installed it?' + ); + }); + + test('returns otel tracer if @opentelemetry/api is installed', async () => { + const tracer = await get_tracer({ is_enabled: true }); + expect(tracer).not.toBe(noop_tracer); + }); +}); diff --git a/packages/kit/src/runtime/telemetry/load_otel.js b/packages/kit/src/runtime/telemetry/load_otel.js new file mode 100644 index 000000000000..4e37b357857f --- /dev/null +++ b/packages/kit/src/runtime/telemetry/load_otel.js @@ -0,0 +1,18 @@ +/** @import { Tracer, SpanStatusCode } from '@opentelemetry/api' */ + +/** @type {Promise<{ tracer: Tracer, SpanStatusCode: typeof SpanStatusCode } | null> | null} */ +let otel_result = null; + +export function load_otel() { + if (otel_result) return otel_result; + otel_result = import('@opentelemetry/api') + .then((module) => { + const { trace, SpanStatusCode } = module; + return { + tracer: trace.getTracer('sveltekit'), + SpanStatusCode + }; + }) + .catch(() => null); + return otel_result; +} diff --git a/packages/kit/src/runtime/telemetry/noop.js b/packages/kit/src/runtime/telemetry/noop.js new file mode 100644 index 000000000000..47413c5df550 --- /dev/null +++ b/packages/kit/src/runtime/telemetry/noop.js @@ -0,0 +1,81 @@ +/** @import { Tracer, Span, SpanContext } from '@opentelemetry/api' */ + +/** + * Tracer implementation that does nothing (null object). + * @type {Tracer} + */ +export const noop_tracer = { + /** + * @returns {Span} + */ + startSpan() { + return noop_span; + }, + + /** + * @param {unknown} _name + * @param {unknown} arg_1 + * @param {unknown} [arg_2] + * @param {Function} [arg_3] + * @returns {unknown} + */ + startActiveSpan(_name, arg_1, arg_2, arg_3) { + if (typeof arg_1 === 'function') { + return arg_1(noop_span); + } + if (typeof arg_2 === 'function') { + return arg_2(noop_span); + } + if (typeof arg_3 === 'function') { + return arg_3(noop_span); + } + } +}; + +/** + * @type {Span} + */ +export const noop_span = { + spanContext() { + return noop_span_context; + }, + setAttribute() { + return this; + }, + setAttributes() { + return this; + }, + addEvent() { + return this; + }, + setStatus() { + return this; + }, + updateName() { + return this; + }, + end() { + return this; + }, + isRecording() { + return false; + }, + recordException() { + return this; + }, + addLink() { + return this; + }, + addLinks() { + return this; + } +}; + +/** + * @type {SpanContext} + */ +const noop_span_context = { + traceId: '', + spanId: '', + traceFlags: 0 +}; diff --git a/packages/kit/src/runtime/telemetry/record_span.js b/packages/kit/src/runtime/telemetry/record_span.js new file mode 100644 index 000000000000..2401643a4a7f --- /dev/null +++ b/packages/kit/src/runtime/telemetry/record_span.js @@ -0,0 +1,75 @@ +/** @import { Attributes, Span, Tracer } from '@opentelemetry/api' */ +import { HttpError, Redirect } from '@sveltejs/kit/internal'; +import { load_otel } from './load_otel.js'; +import { noop_span } from './noop.js'; + +/** + * @template T + * @param {Object} options + * @param {string} options.name + * @param {Tracer} options.tracer + * @param {Attributes} options.attributes + * @param {function(Span): Promise} options.fn + * @returns {Promise} + */ +export async function record_span({ name, tracer, attributes, fn }) { + const otel = await load_otel(); + if (otel === null) { + return fn(noop_span); + } + + const { SpanStatusCode } = otel; + + return tracer.startActiveSpan(name, { attributes }, async (span) => { + try { + const result = await fn(span); + span.end(); + return result; + } catch (error) { + if (error instanceof HttpError) { + span.setAttributes({ + [`${name}.result.type`]: 'known_error', + [`${name}.result.status`]: error.status, + [`${name}.result.message`]: error.body.message + }); + if (error.status >= 500) { + span.recordException({ + name: 'HttpError', + message: error.body.message + }); + span.setStatus({ + code: SpanStatusCode.ERROR, + message: error.body.message + }); + } + } else if (error instanceof Redirect) { + span.setAttributes({ + [`${name}.result.type`]: 'redirect', + [`${name}.result.status`]: error.status, + [`${name}.result.location`]: error.location + }); + } else if (error instanceof Error) { + span.setAttributes({ + [`${name}.result.type`]: 'unknown_error' + }); + span.recordException({ + name: error.name, + message: error.message, + stack: error.stack + }); + span.setStatus({ + code: SpanStatusCode.ERROR, + message: error.message + }); + } else { + span.setAttributes({ + [`${name}.result.type`]: 'unknown_error' + }); + span.setStatus({ code: SpanStatusCode.ERROR }); + } + span.end(); + + throw error; + } + }); +} diff --git a/packages/kit/src/runtime/telemetry/record_span.spec.js b/packages/kit/src/runtime/telemetry/record_span.spec.js new file mode 100644 index 000000000000..9be6bd2c407d --- /dev/null +++ b/packages/kit/src/runtime/telemetry/record_span.spec.js @@ -0,0 +1,198 @@ +import { describe, test, expect, vi } from 'vitest'; +import { record_span } from './record_span.js'; +import { noop_span, noop_tracer } from './noop.js'; +import * as load_otel from './load_otel.js'; +import { HttpError, Redirect } from '@sveltejs/kit/internal'; + +const create_mock_span = () => + /** @type {import('@opentelemetry/api').Span} */ ( + /** @type {unknown} */ ({ + end: vi.fn(), + setAttributes: vi.fn(), + setStatus: vi.fn(), + recordException: vi.fn() + }) + ); + +/** @type {() => { tracer: import('@opentelemetry/api').Tracer, span: import('@opentelemetry/api').Span } } */ +const create_mock_tracer = () => { + const span = create_mock_span(); + const tracer = { + startActiveSpan: vi.fn().mockImplementation((_name, _options, fn) => { + return fn(span); + }), + startSpan: vi.fn().mockImplementation((_name, _options, fn) => { + return fn(span); + }) + }; + return { tracer, span }; +}; + +describe('record_span', () => { + test('runs function with noop span if @opentelemetry/api is not available', async () => { + const spy = vi.spyOn(load_otel, 'load_otel').mockResolvedValue(null); + const fn = vi.fn().mockResolvedValue('result'); + + const result = await record_span({ name: 'test', tracer: noop_tracer, attributes: {}, fn }); + expect(result).toBe('result'); + expect(fn).toHaveBeenCalledWith(noop_span); + spy.mockRestore(); + }); + + test('runs function with span if @opentelemetry/api is available', async () => { + const fn = vi.fn().mockResolvedValue('result'); + const result = await record_span({ + name: 'test', + tracer: create_mock_tracer().tracer, + attributes: {}, + fn + }); + expect(result).toBe('result'); + expect(fn).not.toHaveBeenCalledWith(noop_span); + }); + + test('successful function returns result, attaching correct attributes', async () => { + const { tracer, span } = create_mock_tracer(); + const fn = vi.fn().mockResolvedValue('result'); + const result = await record_span({ + name: 'test', + tracer, + attributes: { 'test-attribute': true }, + fn + }); + expect(result).toBe('result'); + expect(tracer.startActiveSpan).toHaveBeenCalledWith( + 'test', + { attributes: { 'test-attribute': true } }, + expect.any(Function) + ); + expect(span.end).toHaveBeenCalled(); + }); + + test('HttpError sets correct attributes and re-throw, does set status for >=500', async () => { + const { tracer, span } = create_mock_tracer(); + const error = new HttpError(500, 'Found but badly'); + const error_fn = vi.fn().mockRejectedValue(error); + + await expect( + record_span({ + name: 'test', + tracer, + attributes: {}, + fn: error_fn + }) + ).rejects.toBe(error); + + expect(span.setAttributes).toHaveBeenCalledWith({ + 'test.result.type': 'known_error', + 'test.result.status': 500, + 'test.result.message': 'Found but badly' + }); + expect(span.recordException).toHaveBeenCalledWith({ + name: 'HttpError', + message: 'Found but badly' + }); + expect(span.setStatus).toHaveBeenCalledWith({ + code: expect.any(Number), + message: 'Found but badly' + }); + expect(span.end).toHaveBeenCalled(); + }); + + test('HttpError sets correct attributes and re-throws, does not set status for <500', async () => { + const { tracer, span } = create_mock_tracer(); + const error = new HttpError(404, 'Not found'); + const error_fn = vi.fn().mockRejectedValue(error); + + await expect( + record_span({ + name: 'test', + tracer, + attributes: {}, + fn: error_fn + }) + ).rejects.toBe(error); + + expect(span.setAttributes).toHaveBeenCalledWith({ + 'test.result.type': 'known_error', + 'test.result.status': 404, + 'test.result.message': 'Not found' + }); + expect(span.end).toHaveBeenCalled(); + }); + + test('Redirect sets correct attributes and re-throws', async () => { + const { tracer, span } = create_mock_tracer(); + const error = new Redirect(302, '/redirect-location'); + const error_fn = vi.fn().mockRejectedValue(error); + + await expect( + record_span({ + name: 'test', + tracer, + attributes: {}, + fn: error_fn + }) + ).rejects.toBe(error); + + expect(span.setAttributes).toHaveBeenCalledWith({ + 'test.result.type': 'redirect', + 'test.result.status': 302, + 'test.result.location': '/redirect-location' + }); + expect(span.setStatus).not.toHaveBeenCalled(); + expect(span.end).toHaveBeenCalled(); + }); + + test('Generic Error sets correct attributes and re-throws', async () => { + const { tracer, span } = create_mock_tracer(); + const error = new Error('Something went wrong'); + const error_fn = vi.fn().mockRejectedValue(error); + + await expect( + record_span({ + name: 'test', + tracer, + attributes: {}, + fn: error_fn + }) + ).rejects.toThrow(error); + + expect(span.setAttributes).toHaveBeenCalledWith({ + 'test.result.type': 'unknown_error' + }); + expect(span.recordException).toHaveBeenCalledWith({ + name: 'Error', + message: 'Something went wrong', + stack: error.stack + }); + expect(span.setStatus).toHaveBeenCalledWith({ + code: expect.any(Number), + message: 'Something went wrong' + }); + expect(span.end).toHaveBeenCalled(); + }); + + test('Non-Error object sets correct attributes and re-throws', async () => { + const { tracer, span } = create_mock_tracer(); + const error = 'string error'; + const error_fn = vi.fn().mockRejectedValue(error); + + await expect( + record_span({ + name: 'test', + tracer, + attributes: {}, + fn: error_fn + }) + ).rejects.toThrow(error); + + expect(span.setAttributes).toHaveBeenCalledWith({ + 'test.result.type': 'unknown_error' + }); + expect(span.setStatus).toHaveBeenCalledWith({ + code: expect.any(Number) + }); + expect(span.end).toHaveBeenCalled(); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8bc051b6d2b1..e69cb7d49fcf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -416,6 +416,9 @@ importers: specifier: ^3.0.0 version: 3.0.0 devDependencies: + '@opentelemetry/api': + specifier: ^1.0.0 + version: 1.9.0 '@playwright/test': specifier: 'catalog:' version: 1.51.1 @@ -2062,6 +2065,10 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + '@opentelemetry/api@1.9.0': + resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + engines: {node: '>=8.0.0'} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -5467,6 +5474,8 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 + '@opentelemetry/api@1.9.0': {} + '@pkgjs/parseargs@0.11.0': optional: true From 78a65eac92d7a0c0bc2f70f1b8940feac5b87446 Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Wed, 23 Jul 2025 02:03:45 -0600 Subject: [PATCH 02/74] feat: Add tracing to `load`, server actions, and `handle`/`resolve` (#13900) * feat: Add tracing to `load`, server actions, and `handle`/`resolve` * feat: add universal IDs to client nodes * approve otp dep build * add links for docs * since tags * clarify * explain util * import the rest of the types through jsdoc import statements * generate types --------- Co-authored-by: Chew Tee Ming --- package.json | 1 + packages/kit/src/core/config/index.spec.js | 60 ++ packages/kit/src/core/config/options.js | 9 + packages/kit/src/core/sync/write_server.js | 6 + packages/kit/src/exports/hooks/sequence.js | 91 +-- .../kit/src/exports/hooks/sequence.spec.js | 19 +- packages/kit/src/exports/public.d.ts | 43 ++ packages/kit/src/runtime/client/client.js | 23 +- packages/kit/src/runtime/server/data/index.js | 1 + .../kit/src/runtime/server/page/actions.js | 71 ++- packages/kit/src/runtime/server/page/index.js | 8 +- .../kit/src/runtime/server/page/load_data.js | 252 ++++---- .../runtime/server/page/respond_with_error.js | 5 +- packages/kit/src/runtime/server/respond.js | 89 ++- packages/kit/src/runtime/server/utils.js | 13 + packages/kit/src/runtime/shared.js | 20 + .../kit/src/runtime/telemetry/get_tracer.js | 17 +- .../src/runtime/telemetry/get_tracer.spec.js | 11 +- packages/kit/src/types/internal.d.ts | 2 + packages/kit/test/apps/basics/.gitignore | 3 +- packages/kit/test/apps/basics/package.json | 3 + .../kit/test/apps/basics/src/hooks.server.js | 8 + .../apps/basics/src/lib/tracing-config.js | 48 ++ .../routes/tracing/http-error/+page.server.js | 5 + .../routes/tracing/http-error/+page.svelte | 1 + .../tracing/non-error-object/+page.server.js | 3 + .../one/two/three/[...four]/+page.svelte | 1 + .../routes/tracing/redirect/+page.server.js | 5 + .../tracing/regular-error/+page.server.js | 3 + .../kit/test/apps/basics/svelte.config.js | 5 +- .../kit/test/apps/basics/test/server.test.js | 467 +++++++++++++++ packages/kit/test/types.d.ts | 21 + packages/kit/test/utils.d.ts | 2 + packages/kit/test/utils.js | 35 ++ packages/kit/types/index.d.ts | 46 +- pnpm-lock.yaml | 536 ++++++++++++++++++ 36 files changed, 1701 insertions(+), 232 deletions(-) create mode 100644 packages/kit/test/apps/basics/src/lib/tracing-config.js create mode 100644 packages/kit/test/apps/basics/src/routes/tracing/http-error/+page.server.js create mode 100644 packages/kit/test/apps/basics/src/routes/tracing/http-error/+page.svelte create mode 100644 packages/kit/test/apps/basics/src/routes/tracing/non-error-object/+page.server.js create mode 100644 packages/kit/test/apps/basics/src/routes/tracing/one/two/three/[...four]/+page.svelte create mode 100644 packages/kit/test/apps/basics/src/routes/tracing/redirect/+page.server.js create mode 100644 packages/kit/test/apps/basics/src/routes/tracing/regular-error/+page.server.js create mode 100644 packages/kit/test/types.d.ts diff --git a/package.json b/package.json index e36ec2939797..c50d3c8c8e70 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "@parcel/watcher", "esbuild", "netlify-cli", + "protobufjs", "rolldown", "sharp", "svelte-preprocess", diff --git a/packages/kit/src/core/config/index.spec.js b/packages/kit/src/core/config/index.spec.js index 419f30416d9c..d1a954ac2f87 100644 --- a/packages/kit/src/core/config/index.spec.js +++ b/packages/kit/src/core/config/index.spec.js @@ -76,6 +76,9 @@ const get_defaults = (prefix = '') => ({ publicPrefix: 'PUBLIC_', privatePrefix: '' }, + experimental: { + tracing: undefined + }, files: { assets: join(prefix, 'static'), hooks: { @@ -404,3 +407,60 @@ test('errors on loading config with incorrect default export', async () => { 'The Svelte config file must have a configuration object as its default export. See https://svelte.dev/docs/kit/configuration' ); }); + +test('accepts valid tracing values', () => { + assert.doesNotThrow(() => { + validate_config({ + kit: { + experimental: { + tracing: 'server' + } + } + }); + }); + + assert.doesNotThrow(() => { + validate_config({ + kit: { + experimental: { + tracing: undefined + } + } + }); + }); +}); + +test('errors on invalid tracing values', () => { + assert.throws(() => { + validate_config({ + kit: { + experimental: { + // @ts-expect-error - given value expected to throw + tracing: true + } + } + }); + }, /^config\.kit\.experimental\.tracing should be undefined or "server"$/); + + assert.throws(() => { + validate_config({ + kit: { + experimental: { + // @ts-expect-error - given value expected to throw + tracing: false + } + } + }); + }, /^config\.kit\.experimental\.tracing should be undefined or "server"$/); + + assert.throws(() => { + validate_config({ + kit: { + experimental: { + // @ts-expect-error - given value expected to throw + tracing: 'client' + } + } + }); + }, /^config\.kit\.experimental\.tracing should be undefined or "server"$/); +}); diff --git a/packages/kit/src/core/config/options.js b/packages/kit/src/core/config/options.js index a2b9bb81759d..cd937a5af528 100644 --- a/packages/kit/src/core/config/options.js +++ b/packages/kit/src/core/config/options.js @@ -120,6 +120,15 @@ const options = object( privatePrefix: string('') }), + experimental: object({ + tracing: validate(undefined, (input, keypath) => { + if (input !== 'server') { + throw new Error(`${keypath} should be undefined or "server"`); + } + return input; + }) + }), + files: object({ assets: string('static'), hooks: object({ diff --git a/packages/kit/src/core/sync/write_server.js b/packages/kit/src/core/sync/write_server.js index 5e93d5c1cd25..a2d6f3b99eb3 100644 --- a/packages/kit/src/core/sync/write_server.js +++ b/packages/kit/src/core/sync/write_server.js @@ -33,6 +33,11 @@ import { set_building, set_prerendering } from '__sveltekit/environment'; import { set_assets } from '__sveltekit/paths'; import { set_manifest, set_read_implementation } from '__sveltekit/server'; import { set_private_env, set_public_env, set_safe_public_env } from '${runtime_directory}/shared-server.js'; +import { get_tracer, enable_tracing } from '${runtime_directory}/telemetry/get_tracer.js'; + +if (${s(config.kit.experimental.tracing === 'server')}) { + enable_tracing(); +} export const options = { app_template_contains_nonce: ${template.includes('%sveltekit.nonce%')}, @@ -60,6 +65,7 @@ export const options = { .replace(/%sveltekit\.status%/g, '" + status + "') .replace(/%sveltekit\.error\.message%/g, '" + message + "')} }, + tracer: get_tracer(), version_hash: ${s(hash(config.kit.version.name))} }; diff --git a/packages/kit/src/exports/hooks/sequence.js b/packages/kit/src/exports/hooks/sequence.js index 2c0fc3460007..443be6c24cd4 100644 --- a/packages/kit/src/exports/hooks/sequence.js +++ b/packages/kit/src/exports/hooks/sequence.js @@ -1,3 +1,9 @@ +/** @import { Handle, RequestEvent, ResolveOptions } from '@sveltejs/kit' */ +/** @import { MaybePromise } from 'types' */ +import { with_event } from '../../runtime/app/server/event.js'; +import { get_tracer } from '../../runtime/telemetry/get_tracer.js'; +import { record_span } from '../../runtime/telemetry/record_span.js'; + /** * A helper function for sequencing multiple `handle` calls in a middleware-like manner. * The behavior for the `handle` options is as follows: @@ -66,56 +72,77 @@ * first post-processing * ``` * - * @param {...import('@sveltejs/kit').Handle} handlers The chain of `handle` functions - * @returns {import('@sveltejs/kit').Handle} + * @param {...Handle} handlers The chain of `handle` functions + * @returns {Handle} */ export function sequence(...handlers) { const length = handlers.length; if (!length) return ({ event, resolve }) => resolve(event); - return ({ event, resolve }) => { + return async ({ event, resolve }) => { + // there's an assumption here that people aren't doing something insane like sequence(() => {}, sequence(() => {})) + // worst case there is that future spans get a lower-down span as their root span -- the tracing would still work, + // it'd just look a little weird + const { rootSpan } = event.tracing; + const tracer = await get_tracer(); return apply_handle(0, event, {}); /** * @param {number} i - * @param {import('@sveltejs/kit').RequestEvent} event - * @param {import('@sveltejs/kit').ResolveOptions | undefined} parent_options - * @returns {import('types').MaybePromise} + * @param {RequestEvent} event + * @param {ResolveOptions | undefined} parent_options + * @returns {MaybePromise} */ function apply_handle(i, event, parent_options) { const handle = handlers[i]; - return handle({ - event, - resolve: (event, options) => { - /** @type {import('@sveltejs/kit').ResolveOptions['transformPageChunk']} */ - const transformPageChunk = async ({ html, done }) => { - if (options?.transformPageChunk) { - html = (await options.transformPageChunk({ html, done })) ?? ''; - } + return record_span({ + tracer, + name: 'sveltekit.handle.child', + attributes: { + 'sveltekit.handle.child.index': i + }, + fn: async (span) => { + const traced_event = { ...event, tracing: { rootSpan, currentSpan: span } }; + return await with_event(traced_event, () => + handle({ + event: traced_event, + resolve: (event, options) => { + /** @type {ResolveOptions['transformPageChunk']} */ + const transformPageChunk = async ({ html, done }) => { + if (options?.transformPageChunk) { + html = (await options.transformPageChunk({ html, done })) ?? ''; + } - if (parent_options?.transformPageChunk) { - html = (await parent_options.transformPageChunk({ html, done })) ?? ''; - } + if (parent_options?.transformPageChunk) { + html = (await parent_options.transformPageChunk({ html, done })) ?? ''; + } - return html; - }; + return html; + }; - /** @type {import('@sveltejs/kit').ResolveOptions['filterSerializedResponseHeaders']} */ - const filterSerializedResponseHeaders = - parent_options?.filterSerializedResponseHeaders ?? - options?.filterSerializedResponseHeaders; + /** @type {ResolveOptions['filterSerializedResponseHeaders']} */ + const filterSerializedResponseHeaders = + parent_options?.filterSerializedResponseHeaders ?? + options?.filterSerializedResponseHeaders; - /** @type {import('@sveltejs/kit').ResolveOptions['preload']} */ - const preload = parent_options?.preload ?? options?.preload; + /** @type {ResolveOptions['preload']} */ + const preload = parent_options?.preload ?? options?.preload; - return i < length - 1 - ? apply_handle(i + 1, event, { - transformPageChunk, - filterSerializedResponseHeaders, - preload - }) - : resolve(event, { transformPageChunk, filterSerializedResponseHeaders, preload }); + return i < length - 1 + ? apply_handle(i + 1, event, { + transformPageChunk, + filterSerializedResponseHeaders, + preload + }) + : resolve(event, { + transformPageChunk, + filterSerializedResponseHeaders, + preload + }); + } + }) + ); } }); } diff --git a/packages/kit/src/exports/hooks/sequence.spec.js b/packages/kit/src/exports/hooks/sequence.spec.js index 0829e90a92e6..79a9eee95aa7 100644 --- a/packages/kit/src/exports/hooks/sequence.spec.js +++ b/packages/kit/src/exports/hooks/sequence.spec.js @@ -4,6 +4,10 @@ import { installPolyfills } from '../node/polyfills.js'; installPolyfills(); +const dummy_event = /** @type {import('@sveltejs/kit').RequestEvent} */ ({ + tracing: { rootSpan: {} } +}); + test('applies handlers in sequence', async () => { /** @type {string[]} */ const order = []; @@ -29,10 +33,9 @@ test('applies handlers in sequence', async () => { } ); - const event = /** @type {import('@sveltejs/kit').RequestEvent} */ ({}); const response = new Response(); - assert.equal(await handler({ event, resolve: () => response }), response); + assert.equal(await handler({ event: dummy_event, resolve: () => response }), response); expect(order).toEqual(['1a', '2a', '3a', '3b', '2b', '1b']); }); @@ -47,9 +50,8 @@ test('uses transformPageChunk option passed to non-terminal handle function', as async ({ event, resolve }) => resolve(event) ); - const event = /** @type {import('@sveltejs/kit').RequestEvent} */ ({}); const response = await handler({ - event, + event: dummy_event, resolve: async (_event, opts = {}) => { let html = ''; @@ -84,9 +86,8 @@ test('merges transformPageChunk option', async () => { } ); - const event = /** @type {import('@sveltejs/kit').RequestEvent} */ ({}); const response = await handler({ - event, + event: dummy_event, resolve: async (_event, opts = {}) => { let html = ''; @@ -117,9 +118,8 @@ test('uses first defined preload option', async () => { } ); - const event = /** @type {import('@sveltejs/kit').RequestEvent} */ ({}); const response = await handler({ - event, + event: dummy_event, resolve: (_event, opts = {}) => { let html = ''; @@ -150,9 +150,8 @@ test('uses first defined filterSerializedResponseHeaders option', async () => { } ); - const event = /** @type {import('@sveltejs/kit').RequestEvent} */ ({}); const response = await handler({ - event, + event: dummy_event, resolve: (_event, opts = {}) => { let html = ''; diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index afc5f1d6d450..d98f1fb11786 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -18,6 +18,7 @@ import { } from '../types/private.js'; import { BuildData, SSRNodeLoader, SSRRoute, ValidatedConfig } from 'types'; import type { SvelteConfig } from '@sveltejs/vite-plugin-svelte'; +import { Span } from '@opentelemetry/api'; export { PrerenderOption } from '../types/private.js'; @@ -401,6 +402,15 @@ export interface KitConfig { */ privatePrefix?: string; }; + /** Experimental features. Here be dragons. Breaking changes may occur in minor releases. */ + experimental?: { + /** + * Whether to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), and [form actions](https://svelte.dev/docs/kit/form-actions). + * @default undefined + * @since 2.26.0 // TODO: update this before publishing + */ + tracing?: 'server'; + }; /** * Where to find various files within your project. */ @@ -967,6 +977,17 @@ export interface LoadEvent< * ``` */ untrack: (fn: () => T) => T; + + /** + * Access to spans for tracing. If tracing is not enabled or the function is being run in the browser, these spans will do nothing.\ + * @since 2.26.0 // TODO: update this before publishing + */ + tracing: { + /** The root span for the request. This span is named `sveltekit.handle.root`. */ + rootSpan: Span; + /** The span associated with the current `load` function. */ + currentSpan: Span; + }; } export interface NavigationEvent< @@ -1242,6 +1263,17 @@ export interface RequestEvent< * `true` for `+server.js` calls coming from SvelteKit without the overhead of actually making an HTTP request. This happens when you make same-origin `fetch` requests on the server. */ isSubRequest: boolean; + + /** + * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. + * @since 2.26.0 // TODO: update this before publishing + */ + tracing: { + /** The root span for the request. This span is named `sveltekit.handle.root`. */ + rootSpan: Span; + /** The span associated with the current `handle` hook, `load` function, or form action. */ + currentSpan: Span; + }; } /** @@ -1398,6 +1430,17 @@ export interface ServerLoadEvent< * ``` */ untrack: (fn: () => T) => T; + + /** + * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. + * @since 2.26.0 // TODO: update this before publishing + */ + tracing: { + /** The root span for the request. This span is named `sveltekit.handle.root`. */ + rootSpan: Span; + /** The span associated with the current server `load` function. */ + currentSpan: Span; + }; } /** diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js index 6e027cb57677..d70003bf9c25 100644 --- a/packages/kit/src/runtime/client/client.js +++ b/packages/kit/src/runtime/client/client.js @@ -39,11 +39,17 @@ import { } from './constants.js'; import { validate_page_exports } from '../../utils/exports.js'; import { compact } from '../../utils/array.js'; -import { INVALIDATED_PARAM, TRAILING_SLASH_PARAM, validate_depends } from '../shared.js'; +import { + INVALIDATED_PARAM, + TRAILING_SLASH_PARAM, + validate_depends, + validate_load_response +} from '../shared.js'; import { get_message, get_status } from '../../utils/error.js'; import { writable } from 'svelte/store'; import { page, update, navigating } from './state.svelte.js'; import { add_data_suffix, add_resolution_suffix } from '../pathname.js'; +import { noop_span } from '../telemetry/noop.js'; export { load_css }; @@ -670,6 +676,7 @@ async function load_node({ loader, parent, url, params, route, server_data_node /** @type {import('@sveltejs/kit').LoadEvent} */ const load_input = { + tracing: { rootSpan: noop_span, currentSpan: noop_span }, route: new Proxy(route, { get: (target, key) => { if (is_tracking) { @@ -762,19 +769,7 @@ async function load_node({ loader, parent, url, params, route, server_data_node try { lock_fetch(); data = (await node.universal.load.call(null, load_input)) ?? null; - if (data != null && Object.getPrototypeOf(data) !== Object.prototype) { - throw new Error( - `a load function related to route '${route.id}' returned ${ - typeof data !== 'object' - ? `a ${typeof data}` - : data instanceof Response - ? 'a Response object' - : Array.isArray(data) - ? 'an array' - : 'a non-plain object' - }, but must return a plain object at the top level (i.e. \`return {...}\`)` - ); - } + validate_load_response(data, `related to route '${route.id}'`); } finally { unlock_fetch(); } diff --git a/packages/kit/src/runtime/server/data/index.js b/packages/kit/src/runtime/server/data/index.js index 0c5d8f1d0ecf..c63fc8654256 100644 --- a/packages/kit/src/runtime/server/data/index.js +++ b/packages/kit/src/runtime/server/data/index.js @@ -63,6 +63,7 @@ export async function render_data( event: new_event, state, node, + tracer: await options.tracer, parent: async () => { /** @type {Record} */ const data = {}; diff --git a/packages/kit/src/runtime/server/page/actions.js b/packages/kit/src/runtime/server/page/actions.js index bd44060bfd2a..3db90d24d740 100644 --- a/packages/kit/src/runtime/server/page/actions.js +++ b/packages/kit/src/runtime/server/page/actions.js @@ -1,3 +1,6 @@ +/** @import { Tracer } from '@opentelemetry/api' */ +/** @import { RequestEvent, ActionResult, Actions } from '@sveltejs/kit' */ +/** @import { SSROptions, SSRNode, ServerNode, ServerHooks } from 'types' */ import * as devalue from 'devalue'; import { DEV } from 'esm-env'; import { json } from '@sveltejs/kit'; @@ -6,8 +9,9 @@ import { get_status, normalize_error } from '../../../utils/error.js'; import { is_form_content_type, negotiate } from '../../../utils/http.js'; import { handle_error_and_jsonify } from '../utils.js'; import { with_event } from '../../app/server/event.js'; +import { record_span } from '../../telemetry/record_span.js'; -/** @param {import('@sveltejs/kit').RequestEvent} event */ +/** @param {RequestEvent} event */ export function is_action_json_request(event) { const accept = negotiate(event.request.headers.get('accept') ?? '*/*', [ 'application/json', @@ -18,9 +22,9 @@ export function is_action_json_request(event) { } /** - * @param {import('@sveltejs/kit').RequestEvent} event - * @param {import('types').SSROptions} options - * @param {import('types').SSRNode['server'] | undefined} server + * @param {RequestEvent} event + * @param {SSROptions} options + * @param {SSRNode['server'] | undefined} server */ export async function handle_action_json_request(event, options, server) { const actions = server?.actions; @@ -51,7 +55,7 @@ export async function handle_action_json_request(event, options, server) { check_named_default_separate(actions); try { - const data = await call_action(event, actions); + const data = await call_action(event, actions, await options.tracer); if (__SVELTEKIT_DEV__) { validate_action_return(data); @@ -111,7 +115,7 @@ function check_incorrect_fail_use(error) { } /** - * @param {import('@sveltejs/kit').Redirect} redirect + * @param {Redirect} redirect */ export function action_json_redirect(redirect) { return action_json({ @@ -122,7 +126,7 @@ export function action_json_redirect(redirect) { } /** - * @param {import('@sveltejs/kit').ActionResult} data + * @param {ActionResult} data * @param {ResponseInit} [init] */ function action_json(data, init) { @@ -130,18 +134,19 @@ function action_json(data, init) { } /** - * @param {import('@sveltejs/kit').RequestEvent} event + * @param {RequestEvent} event */ export function is_action_request(event) { return event.request.method === 'POST'; } /** - * @param {import('@sveltejs/kit').RequestEvent} event - * @param {import('types').SSRNode['server'] | undefined} server - * @returns {Promise} + * @param {RequestEvent} event + * @param {SSRNode['server'] | undefined} server + * @param {Tracer} tracer + * @returns {Promise} */ -export async function handle_action_request(event, server) { +export async function handle_action_request(event, server, tracer) { const actions = server?.actions; if (!actions) { @@ -164,7 +169,7 @@ export async function handle_action_request(event, server) { check_named_default_separate(actions); try { - const data = await call_action(event, actions); + const data = await call_action(event, actions, tracer); if (__SVELTEKIT_DEV__) { validate_action_return(data); @@ -203,7 +208,7 @@ export async function handle_action_request(event, server) { } /** - * @param {import('@sveltejs/kit').Actions} actions + * @param {Actions} actions */ function check_named_default_separate(actions) { if (actions.default && Object.keys(actions).length > 1) { @@ -214,11 +219,12 @@ function check_named_default_separate(actions) { } /** - * @param {import('@sveltejs/kit').RequestEvent} event - * @param {NonNullable} actions + * @param {RequestEvent} event + * @param {NonNullable} actions + * @param {Tracer} tracer * @throws {Redirect | HttpError | SvelteKitError | Error} */ -async function call_action(event, actions) { +async function call_action(event, actions, tracer) { const url = new URL(event.request.url); let name = 'default'; @@ -247,7 +253,32 @@ async function call_action(event, actions) { ); } - return with_event(event, () => action(event)); + return record_span({ + name: 'sveltekit.action', + tracer, + attributes: { + 'sveltekit.action.name': name, + 'http.route': event.route.id || 'unknown' + }, + fn: async (action_span) => { + const traced_event = { + ...event, + tracing: { + rootSpan: event.tracing.rootSpan, + currentSpan: action_span + } + }; + const result = await with_event(traced_event, () => action(traced_event)); + if (result instanceof ActionFailure) { + action_span.setAttributes({ + 'sveltekit.action.result.type': 'failure', + 'sveltekit.action.result.status': result.status + }); + } + + return result; + } + }); } /** @param {any} data */ @@ -265,7 +296,7 @@ function validate_action_return(data) { * Try to `devalue.uneval` the data object, and if it fails, return a proper Error with context * @param {any} data * @param {string} route_id - * @param {import('types').ServerHooks['transport']} transport + * @param {ServerHooks['transport']} transport */ export function uneval_action_response(data, route_id, transport) { const replacer = (/** @type {any} */ thing) => { @@ -284,7 +315,7 @@ export function uneval_action_response(data, route_id, transport) { * Try to `devalue.stringify` the data object, and if it fails, return a proper Error with context * @param {any} data * @param {string} route_id - * @param {import('types').ServerHooks['transport']} transport + * @param {ServerHooks['transport']} transport */ function stringify_action_response(data, route_id, transport) { const encoders = Object.fromEntries( diff --git a/packages/kit/src/runtime/server/page/index.js b/packages/kit/src/runtime/server/page/index.js index de17e7666b0d..3283e836ef37 100644 --- a/packages/kit/src/runtime/server/page/index.js +++ b/packages/kit/src/runtime/server/page/index.js @@ -56,7 +56,7 @@ export async function render_page(event, page, options, manifest, state, nodes, if (is_action_request(event)) { // for action requests, first call handler in +page.server.js // (this also determines status code) - action_result = await handle_action_request(event, leaf_node.server); + action_result = await handle_action_request(event, leaf_node.server, await options.tracer); if (action_result?.type === 'redirect') { return redirect_response(action_result.status, action_result.location); } @@ -166,7 +166,8 @@ export async function render_page(event, page, options, manifest, state, nodes, if (parent) Object.assign(data, parent.data); } return data; - } + }, + tracer: await options.tracer }); } catch (e) { load_error = /** @type {Error} */ (e); @@ -194,7 +195,8 @@ export async function render_page(event, page, options, manifest, state, nodes, resolve_opts, server_data_promise: server_promises[i], state, - csr + csr, + tracer: await options.tracer }); } catch (e) { load_error = /** @type {Error} */ (e); diff --git a/packages/kit/src/runtime/server/page/load_data.js b/packages/kit/src/runtime/server/page/load_data.js index 74bd7444af4f..45ec2209b7cd 100644 --- a/packages/kit/src/runtime/server/page/load_data.js +++ b/packages/kit/src/runtime/server/page/load_data.js @@ -1,8 +1,10 @@ import { DEV } from 'esm-env'; import { disable_search, make_trackable } from '../../../utils/url.js'; -import { validate_depends } from '../../shared.js'; +import { validate_depends, validate_load_response } from '../../shared.js'; import { b64_encode } from '../../utils.js'; import { with_event } from '../../app/server/event.js'; +import { record_span } from '../../telemetry/record_span.js'; +import { get_node_type } from '../utils.js'; /** * Calls the user's server `load` function. @@ -11,10 +13,11 @@ import { with_event } from '../../app/server/event.js'; * state: import('types').SSRState; * node: import('types').SSRNode | undefined; * parent: () => Promise>; + * tracer: import('@opentelemetry/api').Tracer; * }} opts * @returns {Promise} */ -export async function load_server_data({ event, state, node, parent }) { +export async function load_server_data({ event, state, node, parent, tracer }) { if (!node?.server) return null; let is_tracking = true; @@ -68,97 +71,113 @@ export async function load_server_data({ event, state, node, parent }) { let done = false; - const result = await with_event(event, () => - load.call(null, { - ...event, - fetch: (info, init) => { - const url = new URL(info instanceof Request ? info.url : info, event.url); - - if (DEV && done && !uses.dependencies.has(url.href)) { - console.warn( - `${node.server_id}: Calling \`event.fetch(...)\` in a promise handler after \`load(...)\` has returned will not cause the function to re-run when the dependency is invalidated` - ); - } - - // Note: server fetches are not added to uses.depends due to security concerns - return event.fetch(info, init); - }, - /** @param {string[]} deps */ - depends: (...deps) => { - for (const dep of deps) { - const { href } = new URL(dep, event.url); - - if (DEV) { - validate_depends(node.server_id || 'missing route ID', dep); - - if (done && !uses.dependencies.has(href)) { + const result = await record_span({ + name: 'sveltekit.load', + tracer, + attributes: { + 'sveltekit.load.node_id': node.server_id || 'unknown', + 'sveltekit.load.node_type': get_node_type(node.server_id), + 'sveltekit.load.environment': 'server', + 'http.route': event.route.id || 'unknown' + }, + fn: async (span) => { + const rootSpan = event.tracing.rootSpan; + const traced_event = { ...event, tracing: { rootSpan, currentSpan: span } }; + const result = await with_event(traced_event, () => + load.call(null, { + ...traced_event, + fetch: (info, init) => { + const url = new URL(info instanceof Request ? info.url : info, event.url); + + if (DEV && done && !uses.dependencies.has(url.href)) { console.warn( - `${node.server_id}: Calling \`depends(...)\` in a promise handler after \`load(...)\` has returned will not cause the function to re-run when the dependency is invalidated` + `${node.server_id}: Calling \`event.fetch(...)\` in a promise handler after \`load(...)\` has returned will not cause the function to re-run when the dependency is invalidated` ); } - } - uses.dependencies.add(href); - } - }, - params: new Proxy(event.params, { - get: (target, key) => { - if (DEV && done && typeof key === 'string' && !uses.params.has(key)) { - console.warn( - `${node.server_id}: Accessing \`params.${String( - key - )}\` in a promise handler after \`load(...)\` has returned will not cause the function to re-run when the param changes` - ); - } - - if (is_tracking) { - uses.params.add(key); - } - return target[/** @type {string} */ (key)]; - } - }), - parent: async () => { - if (DEV && done && !uses.parent) { - console.warn( - `${node.server_id}: Calling \`parent(...)\` in a promise handler after \`load(...)\` has returned will not cause the function to re-run when parent data changes` - ); - } + // Note: server fetches are not added to uses.depends due to security concerns + return event.fetch(info, init); + }, + /** @param {string[]} deps */ + depends: (...deps) => { + for (const dep of deps) { + const { href } = new URL(dep, event.url); + + if (DEV) { + validate_depends(node.server_id || 'missing route ID', dep); + + if (done && !uses.dependencies.has(href)) { + console.warn( + `${node.server_id}: Calling \`depends(...)\` in a promise handler after \`load(...)\` has returned will not cause the function to re-run when the dependency is invalidated` + ); + } + } + + uses.dependencies.add(href); + } + }, + params: new Proxy(event.params, { + get: (target, key) => { + if (DEV && done && typeof key === 'string' && !uses.params.has(key)) { + console.warn( + `${node.server_id}: Accessing \`params.${String( + key + )}\` in a promise handler after \`load(...)\` has returned will not cause the function to re-run when the param changes` + ); + } + + if (is_tracking) { + uses.params.add(key); + } + return target[/** @type {string} */ (key)]; + } + }), + parent: async () => { + if (DEV && done && !uses.parent) { + console.warn( + `${node.server_id}: Calling \`parent(...)\` in a promise handler after \`load(...)\` has returned will not cause the function to re-run when parent data changes` + ); + } - if (is_tracking) { - uses.parent = true; - } - return parent(); - }, - route: new Proxy(event.route, { - get: (target, key) => { - if (DEV && done && typeof key === 'string' && !uses.route) { - console.warn( - `${node.server_id}: Accessing \`route.${String( - key - )}\` in a promise handler after \`load(...)\` has returned will not cause the function to re-run when the route changes` - ); + if (is_tracking) { + uses.parent = true; + } + return parent(); + }, + route: new Proxy(event.route, { + get: (target, key) => { + if (DEV && done && typeof key === 'string' && !uses.route) { + console.warn( + `${node.server_id}: Accessing \`route.${String( + key + )}\` in a promise handler after \`load(...)\` has returned will not cause the function to re-run when the route changes` + ); + } + + if (is_tracking) { + uses.route = true; + } + return target[/** @type {'id'} */ (key)]; + } + }), + url, + untrack(fn) { + is_tracking = false; + try { + return fn(); + } finally { + is_tracking = true; + } } + }) + ); - if (is_tracking) { - uses.route = true; - } - return target[/** @type {'id'} */ (key)]; - } - }), - url, - untrack(fn) { - is_tracking = false; - try { - return fn(); - } finally { - is_tracking = true; - } - } - }) - ); + return result; + } + }); if (__SVELTEKIT_DEV__) { - validate_load_response(result, node.server_id); + validate_load_response(result, `in ${node.server_id}`); } done = true; @@ -182,6 +201,7 @@ export async function load_server_data({ event, state, node, parent }) { * server_data_promise: Promise; * state: import('types').SSRState; * csr: boolean; + * tracer: import('@opentelemetry/api').Tracer; * }} opts * @returns {Promise> | null>} */ @@ -193,7 +213,8 @@ export async function load_data({ server_data_promise, state, resolve_opts, - csr + csr, + tracer }) { const server_data_node = await server_data_promise; @@ -201,20 +222,39 @@ export async function load_data({ return server_data_node?.data ?? null; } - const result = await node.universal.load.call(null, { - url: event.url, - params: event.params, - data: server_data_node?.data ?? null, - route: event.route, - fetch: create_universal_fetch(event, state, fetched, csr, resolve_opts), - setHeaders: event.setHeaders, - depends: () => {}, - parent, - untrack: (fn) => fn() + const { load } = node.universal; + + const result = await record_span({ + name: 'sveltekit.load', + tracer, + attributes: { + 'sveltekit.load.node_id': node.universal_id || 'unknown', + 'sveltekit.load.node_type': get_node_type(node.universal_id), + 'sveltekit.load.environment': 'server', + 'http.route': event.route.id || 'unknown' + }, + fn: async (span) => { + const rootSpan = event.tracing.rootSpan; + const tracing = { rootSpan, currentSpan: span }; + const result = await load.call(null, { + tracing, + url: event.url, + params: event.params, + data: server_data_node?.data ?? null, + route: event.route, + fetch: create_universal_fetch(event, state, fetched, csr, resolve_opts), + setHeaders: event.setHeaders, + depends: () => {}, + parent, + untrack: (fn) => fn() + }); + + return result; + } }); if (__SVELTEKIT_DEV__) { - validate_load_response(result, node.universal_id); + validate_load_response(result, `in ${node.universal_id}`); } return result ?? null; @@ -398,23 +438,3 @@ async function stream_to_string(stream) { } return result; } - -/** - * @param {any} data - * @param {string} [id] - */ -function validate_load_response(data, id) { - if (data != null && Object.getPrototypeOf(data) !== Object.prototype) { - throw new Error( - `a load function in ${id} returned ${ - typeof data !== 'object' - ? `a ${typeof data}` - : data instanceof Response - ? 'a Response object' - : Array.isArray(data) - ? 'an array' - : 'a non-plain object' - }, but must return a plain object at the top level (i.e. \`return {...}\`)` - ); - } -} diff --git a/packages/kit/src/runtime/server/page/respond_with_error.js b/packages/kit/src/runtime/server/page/respond_with_error.js index bb3e99054507..670870a35291 100644 --- a/packages/kit/src/runtime/server/page/respond_with_error.js +++ b/packages/kit/src/runtime/server/page/respond_with_error.js @@ -46,11 +46,13 @@ export async function respond_with_error({ if (ssr) { state.error = true; + const tracer = await options.tracer; const server_data_promise = load_server_data({ event, state, node: default_layout, + tracer, // eslint-disable-next-line @typescript-eslint/require-await parent: async () => ({}) }); @@ -66,7 +68,8 @@ export async function respond_with_error({ resolve_opts, server_data_promise, state, - csr + csr, + tracer }); branch.push( diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index d37659cf899b..38e71af812bf 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -34,6 +34,7 @@ import { strip_resolution_suffix } from '../pathname.js'; import { with_event } from '../app/server/event.js'; +import { record_span } from '../telemetry/record_span.js'; /* global __SVELTEKIT_ADAPTER_NAME__ */ /* global __SVELTEKIT_DEV__ */ @@ -362,32 +363,68 @@ export async function respond(request, options, manifest, state) { disable_search(url); } - const response = await with_event(event, () => - options.hooks.handle({ - event, - resolve: (event, opts) => - // counter-intuitively, we need to clear the event, so that it's not - // e.g. accessible when loading modules needed to handle the request - with_event(null, () => - resolve(event, page_nodes, opts).then((response) => { - // add headers/cookies here, rather than inside `resolve`, so that we - // can do it once for all responses instead of once per `return` - for (const key in headers) { - const value = headers[key]; - response.headers.set(key, /** @type {string} */ (value)); - } - - add_cookies_to_headers(response.headers, Object.values(new_cookies)); - - if (state.prerendering && event.route.id !== null) { - response.headers.set('x-sveltekit-routeid', encodeURI(event.route.id)); - } - - return response; - }) - ) - }) - ); + const tracer = await options.tracer; + + const response = await record_span({ + name: 'sveltekit.handle.root', + tracer, + attributes: { + 'http.route': event.route.id || 'unknown', + 'http.method': event.request.method, + 'http.url': event.url.href, + 'sveltekit.is_data_request': is_data_request, + 'sveltekit.is_sub_request': event.isSubRequest + }, + fn: async (rootSpan) => { + const traced_event = { ...event, tracing: { rootSpan, currentSpan: rootSpan } }; + return await with_event(traced_event, () => + options.hooks.handle({ + event: traced_event, + resolve: (event, opts) => { + return record_span({ + name: 'sveltekit.resolve.root', + tracer, + attributes: { + 'http.route': event.route.id || 'unknown' + }, + fn: async (resolveSpan) => { + // counter-intuitively, we need to clear the event, so that it's not + // e.g. accessible when loading modules needed to handle the request + return with_event(null, () => + resolve( + { ...event, tracing: { rootSpan, currentSpan: resolveSpan } }, + page_nodes, + opts + ).then((response) => { + // add headers/cookies here, rather than inside `resolve`, so that we + // can do it once for all responses instead of once per `return` + for (const key in headers) { + const value = headers[key]; + response.headers.set(key, /** @type {string} */ (value)); + } + + add_cookies_to_headers(response.headers, Object.values(new_cookies)); + + if (state.prerendering && event.route.id !== null) { + response.headers.set('x-sveltekit-routeid', encodeURI(event.route.id)); + } + + resolveSpan.setAttributes({ + 'http.response.status_code': response.status, + 'http.response.body.size': + response.headers.get('content-length') || 'unknown' + }); + + return response; + }) + ); + } + }); + } + }) + ); + } + }); // respond with 304 if etag matches if (response.status === 200 && response.headers.has('etag')) { diff --git a/packages/kit/src/runtime/server/utils.js b/packages/kit/src/runtime/server/utils.js index 663584760dd7..92ef239bf3e3 100644 --- a/packages/kit/src/runtime/server/utils.js +++ b/packages/kit/src/runtime/server/utils.js @@ -183,3 +183,16 @@ export function has_prerendered_path(manifest, pathname) { (pathname.at(-1) === '/' && manifest._.prerendered_routes.has(pathname.slice(0, -1))) ); } + +/** + * Returns the filename without the extension. e.g., `+page.server`, `+page`, etc. + * @param {string | undefined} node_id + * @returns {string} + */ +export function get_node_type(node_id) { + const parts = node_id?.split('/'); + const filename = parts?.at(-1); + if (!filename) return 'unknown'; + const dot_parts = filename.split('.'); + return dot_parts.slice(0, -1).join('.'); +} diff --git a/packages/kit/src/runtime/shared.js b/packages/kit/src/runtime/shared.js index b5c559b4292c..fc88526fa442 100644 --- a/packages/kit/src/runtime/shared.js +++ b/packages/kit/src/runtime/shared.js @@ -14,3 +14,23 @@ export function validate_depends(route_id, dep) { export const INVALIDATED_PARAM = 'x-sveltekit-invalidated'; export const TRAILING_SLASH_PARAM = 'x-sveltekit-trailing-slash'; + +/** + * @param {any} data + * @param {string} [location_description] + */ +export function validate_load_response(data, location_description) { + if (data != null && Object.getPrototypeOf(data) !== Object.prototype) { + throw new Error( + `a load function ${location_description} returned ${ + typeof data !== 'object' + ? `a ${typeof data}` + : data instanceof Response + ? 'a Response object' + : Array.isArray(data) + ? 'an array' + : 'a non-plain object' + }, but must return a plain object at the top level (i.e. \`return {...}\`)` + ); + } +} diff --git a/packages/kit/src/runtime/telemetry/get_tracer.js b/packages/kit/src/runtime/telemetry/get_tracer.js index 5c7fac29b412..d4198b9330ea 100644 --- a/packages/kit/src/runtime/telemetry/get_tracer.js +++ b/packages/kit/src/runtime/telemetry/get_tracer.js @@ -3,12 +3,23 @@ import { DEV } from 'esm-env'; import { noop_tracer } from './noop.js'; import { load_otel } from './load_otel.js'; +// this is controlled via a global flag because we need to access it in locations where we don't have access to the config +// (specifically, in `sequence`-d handle functions) +// since this is a global flag with a static value, it's safe to set it during server initialization +let is_enabled = false; + +export function enable_tracing() { + is_enabled = true; +} + +export function disable_tracing() { + is_enabled = false; +} + /** - * @param {Object} [options={}] - Configuration options - * @param {boolean} [options.is_enabled=false] - Whether tracing is enabled * @returns {Promise} The tracer instance */ -export async function get_tracer({ is_enabled = false } = {}) { +export async function get_tracer() { if (!is_enabled) { return noop_tracer; } diff --git a/packages/kit/src/runtime/telemetry/get_tracer.spec.js b/packages/kit/src/runtime/telemetry/get_tracer.spec.js index 01a8dc74a9b1..1452527f47f8 100644 --- a/packages/kit/src/runtime/telemetry/get_tracer.spec.js +++ b/packages/kit/src/runtime/telemetry/get_tracer.spec.js @@ -1,23 +1,25 @@ import { describe, test, expect, beforeEach, vi } from 'vitest'; -import { get_tracer } from './get_tracer.js'; +import { disable_tracing, enable_tracing, get_tracer } from './get_tracer.js'; import { noop_tracer } from './noop.js'; import * as load_otel from './load_otel.js'; describe('get_tracer', () => { beforeEach(() => { vi.resetAllMocks(); + disable_tracing(); }); test('returns noop tracer if tracing is disabled', async () => { - const tracer = await get_tracer({ is_enabled: false }); + const tracer = await get_tracer(); expect(tracer).toBe(noop_tracer); }); test('returns noop tracer if @opentelemetry/api is not installed, warning', async () => { + enable_tracing(); vi.spyOn(load_otel, 'load_otel').mockResolvedValue(null); const console_warn_spy = vi.spyOn(console, 'warn'); - const tracer = await get_tracer({ is_enabled: true }); + const tracer = await get_tracer(); expect(tracer).toBe(noop_tracer); expect(console_warn_spy).toHaveBeenCalledWith( 'Tracing is enabled, but `@opentelemetry/api` is not available. Have you installed it?' @@ -25,7 +27,8 @@ describe('get_tracer', () => { }); test('returns otel tracer if @opentelemetry/api is installed', async () => { - const tracer = await get_tracer({ is_enabled: true }); + enable_tracing(); + const tracer = await get_tracer(); expect(tracer).not.toBe(noop_tracer); }); }); diff --git a/packages/kit/src/types/internal.d.ts b/packages/kit/src/types/internal.d.ts index 17e2425e3c17..4354fa2fe055 100644 --- a/packages/kit/src/types/internal.d.ts +++ b/packages/kit/src/types/internal.d.ts @@ -29,6 +29,7 @@ import { RequestOptions, TrailingSlash } from './private.js'; +import { Tracer } from '@opentelemetry/api'; export interface ServerModule { Server: typeof InternalServer; @@ -435,6 +436,7 @@ export interface SSROptions { }): string; error(values: { message: string; status: number }): string; }; + tracer: Promise; version_hash: string; } diff --git a/packages/kit/test/apps/basics/.gitignore b/packages/kit/test/apps/basics/.gitignore index fad4d3e1518d..7bc5d5fff974 100644 --- a/packages/kit/test/apps/basics/.gitignore +++ b/packages/kit/test/apps/basics/.gitignore @@ -1,3 +1,4 @@ /test/errors.json !/.env -/src/routes/routing/symlink-from \ No newline at end of file +/src/routes/routing/symlink-from +/test/spans.jsonl \ No newline at end of file diff --git a/packages/kit/test/apps/basics/package.json b/packages/kit/test/apps/basics/package.json index fb8fa5350dd8..bcd7c3973834 100644 --- a/packages/kit/test/apps/basics/package.json +++ b/packages/kit/test/apps/basics/package.json @@ -17,6 +17,9 @@ "test:server-side-route-resolution:build": "node test/setup.js && node -e \"fs.rmSync('test/errors.json', { force: true })\" && cross-env PUBLIC_PRERENDERING=false ROUTER_RESOLUTION=server playwright test" }, "devDependencies": { + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/sdk-node": "^0.203.0", + "@opentelemetry/sdk-trace-node": "^2.0.1", "@sveltejs/kit": "workspace:^", "@sveltejs/vite-plugin-svelte": "catalog:", "cross-env": "catalog:", diff --git a/packages/kit/test/apps/basics/src/hooks.server.js b/packages/kit/test/apps/basics/src/hooks.server.js index 5976df3f5763..4c13cf54da2b 100644 --- a/packages/kit/test/apps/basics/src/hooks.server.js +++ b/packages/kit/test/apps/basics/src/hooks.server.js @@ -5,6 +5,7 @@ import fs from 'node:fs'; import { COOKIE_NAME } from './routes/cookies/shared'; import { _set_from_init } from './routes/init-hooks/+page.server'; import { getRequestEvent } from '$app/server'; +import '$lib/tracing-config'; /** * Transform an error into a POJO, by copying its `name`, `message` @@ -49,6 +50,13 @@ export const handleError = ({ event, error: e, status, message }) => { }; export const handle = sequence( + ({ event, resolve }) => { + const test_id = !building && event.url.searchParams.get('test_id'); + if (test_id) { + event.tracing.rootSpan.setAttribute('test_id', test_id); + } + return resolve(event); + }, ({ event, resolve }) => { event.locals.key = event.route.id; event.locals.params = event.params; diff --git a/packages/kit/test/apps/basics/src/lib/tracing-config.js b/packages/kit/test/apps/basics/src/lib/tracing-config.js new file mode 100644 index 000000000000..b944279edecc --- /dev/null +++ b/packages/kit/test/apps/basics/src/lib/tracing-config.js @@ -0,0 +1,48 @@ +/** @import {SpanExporter} from '@opentelemetry/sdk-trace-node' */ +/** @import {SpanData} from '../../../../types' */ +import { NodeSDK } from '@opentelemetry/sdk-node'; +import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-node'; +import fs from 'node:fs'; + +/** @implements {SpanExporter} */ +class FilesystemSpanExporter { + #path; + + constructor(path) { + fs.rmSync(path, { force: true }); + this.#path = path; + } + + /** @param {import('@opentelemetry/sdk-trace-node').ReadableSpan[]} spans */ + export(spans) { + // spans have circular references so they can't be naively json-ified + const serialized_spans = spans.map((span) => { + const span_context = span.spanContext(); + /** @type {SpanData} */ + const span_data = { + name: span.name, + status: span.status, + start_time: span.startTime, + end_time: span.endTime, + attributes: span.attributes, + links: span.links, + trace_id: span_context.traceId, + span_id: span_context.spanId, + parent_span_id: span.parentSpanContext?.spanId + }; + return JSON.stringify(span_data); + }); + + fs.appendFileSync(this.#path, serialized_spans.join('\n') + '\n'); + } + shutdown() { + return Promise.resolve(); + } +} + +const filesystemSpanExporter = new FilesystemSpanExporter('test/spans.jsonl'); +const spanProcessor = new SimpleSpanProcessor(filesystemSpanExporter); +export const sdk = new NodeSDK({ + spanProcessor +}); +sdk.start(); diff --git a/packages/kit/test/apps/basics/src/routes/tracing/http-error/+page.server.js b/packages/kit/test/apps/basics/src/routes/tracing/http-error/+page.server.js new file mode 100644 index 000000000000..cdb7c46a0e31 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/tracing/http-error/+page.server.js @@ -0,0 +1,5 @@ +import { error } from '@sveltejs/kit'; + +export async function load() { + error(500, 'Internal server error from tracing test'); +} diff --git a/packages/kit/test/apps/basics/src/routes/tracing/http-error/+page.svelte b/packages/kit/test/apps/basics/src/routes/tracing/http-error/+page.svelte new file mode 100644 index 000000000000..f32044fa6f36 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/tracing/http-error/+page.svelte @@ -0,0 +1 @@ +

This should not render due to load error

diff --git a/packages/kit/test/apps/basics/src/routes/tracing/non-error-object/+page.server.js b/packages/kit/test/apps/basics/src/routes/tracing/non-error-object/+page.server.js new file mode 100644 index 000000000000..1d678adad533 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/tracing/non-error-object/+page.server.js @@ -0,0 +1,3 @@ +export async function load() { + throw 'string error from tracing test'; +} diff --git a/packages/kit/test/apps/basics/src/routes/tracing/one/two/three/[...four]/+page.svelte b/packages/kit/test/apps/basics/src/routes/tracing/one/two/three/[...four]/+page.svelte new file mode 100644 index 000000000000..13c34178c381 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/tracing/one/two/three/[...four]/+page.svelte @@ -0,0 +1 @@ +

Tracing

diff --git a/packages/kit/test/apps/basics/src/routes/tracing/redirect/+page.server.js b/packages/kit/test/apps/basics/src/routes/tracing/redirect/+page.server.js new file mode 100644 index 000000000000..42f1a7375b87 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/tracing/redirect/+page.server.js @@ -0,0 +1,5 @@ +import { redirect } from '@sveltejs/kit'; + +export async function load({ url }) { + redirect(307, `/tracing/one/two/three/four/five${url.search}`); +} diff --git a/packages/kit/test/apps/basics/src/routes/tracing/regular-error/+page.server.js b/packages/kit/test/apps/basics/src/routes/tracing/regular-error/+page.server.js new file mode 100644 index 000000000000..209e1233ac85 --- /dev/null +++ b/packages/kit/test/apps/basics/src/routes/tracing/regular-error/+page.server.js @@ -0,0 +1,3 @@ +export async function load() { + throw new Error('Regular error from tracing test'); +} diff --git a/packages/kit/test/apps/basics/svelte.config.js b/packages/kit/test/apps/basics/svelte.config.js index d2193940f0ab..12f8ebb08a6b 100644 --- a/packages/kit/test/apps/basics/svelte.config.js +++ b/packages/kit/test/apps/basics/svelte.config.js @@ -37,9 +37,12 @@ const config = { version: { name: 'TEST_VERSION' }, + router: { resolution: /** @type {'client' | 'server'} */ (process.env.ROUTER_RESOLUTION) || 'client' - } + }, + + experimental: { tracing: 'server' } } }; diff --git a/packages/kit/test/apps/basics/test/server.test.js b/packages/kit/test/apps/basics/test/server.test.js index e265115c53c2..148a2a821b74 100644 --- a/packages/kit/test/apps/basics/test/server.test.js +++ b/packages/kit/test/apps/basics/test/server.test.js @@ -768,3 +768,470 @@ test.describe('$app/environment', () => { expect(code).not.toContain('browser'); }); }); + +test.describe('tracing', () => { + // Helper function to find the resolve.root span deep in the handle.child chain + /** @param {import('@opentelemetry/sdk-trace-node').ReadableSpan} span */ + /** @returns {import('@opentelemetry/sdk-trace-node').ReadableSpan | null} */ + function findResolveRootSpan(span) { + if (span.name === 'sveltekit.resolve.root') { + return span; + } + for (const child of span.children || []) { + const found = findResolveRootSpan(child); + if (found) return found; + } + return null; + } + + function rand() { + // node 18 doesn't have crypto.randomUUID() and we run tests in node 18 + return Math.random().toString(36).substring(2, 15); + } + + test('correct spans are created for a regular navigation', async ({ page, read_traces }) => { + const test_id = rand(); + await page.goto(`/tracing/one/two/three/four/five?test_id=${test_id}`); + const traces = read_traces(test_id); + expect(traces.length).toBeGreaterThan(0); + + const trace = traces[0]; + const trace_id = trace.trace_id; + + // Verify root span structure + expect(trace).toEqual({ + name: 'sveltekit.handle.root', + status: { code: 0 }, + start_time: [expect.any(Number), expect.any(Number)], + end_time: [expect.any(Number), expect.any(Number)], + attributes: { + 'http.route': '/tracing/one/two/three/[...four]', + 'http.method': 'GET', + 'http.url': expect.stringContaining(`/tracing/one/two/three/four/five?test_id=${test_id}`), + 'sveltekit.is_data_request': false, + 'sveltekit.is_sub_request': false, + test_id + }, + links: [], + trace_id, + span_id: expect.any(String), + children: expect.arrayContaining([ + expect.objectContaining({ + name: 'sveltekit.handle.child', + attributes: expect.objectContaining({ + 'sveltekit.handle.child.index': 0 + }) + }) + ]) + }); + + // Find and verify the resolve.root span + const resolveRootSpan = findResolveRootSpan(trace); + expect(resolveRootSpan).not.toBeNull(); + expect(resolveRootSpan).toEqual({ + name: 'sveltekit.resolve.root', + status: { code: 0 }, + start_time: [expect.any(Number), expect.any(Number)], + end_time: [expect.any(Number), expect.any(Number)], + attributes: { + 'http.route': '/tracing/one/two/three/[...four]', + 'http.response.status_code': 200, + 'http.response.body.size': expect.stringMatching(/^\d+$/) + }, + links: [], + trace_id, + span_id: expect.any(String), + parent_span_id: expect.any(String), + children: [ + { + name: 'sveltekit.load', + status: { code: 0 }, + start_time: [expect.any(Number), expect.any(Number)], + end_time: [expect.any(Number), expect.any(Number)], + attributes: { + 'sveltekit.load.node_id': 'src/routes/+layout.server.js', + 'sveltekit.load.node_type': '+layout.server', + 'sveltekit.load.environment': 'server', + 'http.route': '/tracing/one/two/three/[...four]' + }, + links: [], + trace_id, + span_id: expect.any(String), + parent_span_id: expect.any(String), + children: [] + }, + { + name: 'sveltekit.load', + status: { code: 0 }, + start_time: [expect.any(Number), expect.any(Number)], + end_time: [expect.any(Number), expect.any(Number)], + attributes: { + 'sveltekit.load.node_id': 'src/routes/+layout.js', + 'sveltekit.load.node_type': '+layout', + 'sveltekit.load.environment': 'server', + 'http.route': '/tracing/one/two/three/[...four]' + }, + links: [], + trace_id, + span_id: expect.any(String), + parent_span_id: expect.any(String), + children: [] + } + ] + }); + }); + + test('correct spans are created for HttpError', async ({ page, read_traces }) => { + const test_id = rand(); + const response = await page.goto(`/tracing/http-error?test_id=${test_id}`); + expect(response?.status()).toBe(500); + + const traces = read_traces(test_id); + const trace_id = traces[0].trace_id; + const trace = traces[0]; + + // Verify root span structure + expect(trace).toEqual({ + name: 'sveltekit.handle.root', + status: { code: 0 }, + start_time: [expect.any(Number), expect.any(Number)], + end_time: [expect.any(Number), expect.any(Number)], + attributes: { + 'http.route': '/tracing/http-error', + 'http.method': 'GET', + 'http.url': expect.stringContaining(`/tracing/http-error?test_id=${test_id}`), + 'sveltekit.is_data_request': false, + 'sveltekit.is_sub_request': false, + test_id + }, + links: [], + trace_id, + span_id: expect.any(String), + children: expect.arrayContaining([ + expect.objectContaining({ + name: 'sveltekit.handle.child', + attributes: expect.objectContaining({ + 'sveltekit.handle.child.index': 0 + }) + }) + ]) + }); + + // Find and verify the resolve.root span + const resolveRootSpan = findResolveRootSpan(trace); + expect(resolveRootSpan).not.toBeNull(); + expect(resolveRootSpan).toEqual({ + name: 'sveltekit.resolve.root', + status: { code: 0 }, + start_time: [expect.any(Number), expect.any(Number)], + end_time: [expect.any(Number), expect.any(Number)], + attributes: { + 'http.route': '/tracing/http-error', + 'http.response.status_code': 500, + 'http.response.body.size': expect.stringMatching(/^\d+$/) + }, + links: [], + trace_id, + span_id: expect.any(String), + parent_span_id: expect.any(String), + children: expect.arrayContaining([ + expect.objectContaining({ + name: 'sveltekit.load', + status: { code: 2, message: 'Internal server error from tracing test' }, + attributes: expect.objectContaining({ + 'sveltekit.load.node_id': 'src/routes/tracing/http-error/+page.server.js', + 'sveltekit.load.result.type': 'known_error', + 'sveltekit.load.result.status': 500, + 'sveltekit.load.result.message': 'Internal server error from tracing test' + }) + }) + ]) + }); + }); + + test('correct spans are created for Redirect', async ({ page, read_traces }) => { + const test_id = rand(); + const response = await page.goto(`/tracing/redirect?test_id=${test_id}`); + expect(response?.status()).toBe(200); + + const traces = read_traces(test_id); + expect(traces).toHaveLength(2); + const redirect_trace_id = traces[0].trace_id; + const destination_trace_id = traces[1].trace_id; + + const redirectTrace = traces[0]; + const destinationTrace = traces[1]; + + // Verify redirect trace root span structure + expect(redirectTrace).toEqual({ + name: 'sveltekit.handle.root', + status: { code: 0 }, + start_time: [expect.any(Number), expect.any(Number)], + end_time: [expect.any(Number), expect.any(Number)], + attributes: { + 'http.route': '/tracing/redirect', + 'http.method': 'GET', + 'http.url': expect.stringContaining(`/tracing/redirect?test_id=${test_id}`), + 'sveltekit.is_data_request': false, + 'sveltekit.is_sub_request': false, + test_id + }, + links: [], + trace_id: redirect_trace_id, + span_id: expect.any(String), + children: expect.arrayContaining([ + expect.objectContaining({ + name: 'sveltekit.handle.child', + attributes: expect.objectContaining({ + 'sveltekit.handle.child.index': 0 + }) + }) + ]) + }); + + // Find and verify the redirect resolve.root span + const redirectResolveRootSpan = findResolveRootSpan(redirectTrace); + expect(redirectResolveRootSpan).not.toBeNull(); + expect(redirectResolveRootSpan).toEqual({ + name: 'sveltekit.resolve.root', + status: { code: 0 }, + start_time: [expect.any(Number), expect.any(Number)], + end_time: [expect.any(Number), expect.any(Number)], + attributes: { + 'http.route': '/tracing/redirect', + 'http.response.status_code': 307, + 'http.response.body.size': expect.stringMatching(/^\d+$|^unknown$/) + }, + links: [], + trace_id: redirect_trace_id, + span_id: expect.any(String), + parent_span_id: expect.any(String), + children: expect.arrayContaining([ + expect.objectContaining({ + name: 'sveltekit.load', + status: { code: 0 }, + attributes: expect.objectContaining({ + 'sveltekit.load.node_id': 'src/routes/tracing/redirect/+page.server.js', + 'sveltekit.load.result.type': 'redirect', + 'sveltekit.load.result.status': 307, + 'sveltekit.load.result.location': `/tracing/one/two/three/four/five?test_id=${test_id}` + }) + }) + ]) + }); + + // Verify destination trace root span structure + expect(destinationTrace).toEqual({ + name: 'sveltekit.handle.root', + status: { code: 0 }, + start_time: [expect.any(Number), expect.any(Number)], + end_time: [expect.any(Number), expect.any(Number)], + attributes: { + 'http.route': '/tracing/one/two/three/[...four]', + 'http.method': 'GET', + 'http.url': expect.stringContaining(`/tracing/one/two/three/four/five?test_id=${test_id}`), + 'sveltekit.is_data_request': false, + 'sveltekit.is_sub_request': false, + test_id + }, + links: [], + trace_id: destination_trace_id, + span_id: expect.any(String), + children: expect.arrayContaining([ + expect.objectContaining({ + name: 'sveltekit.handle.child', + attributes: expect.objectContaining({ + 'sveltekit.handle.child.index': 0 + }) + }) + ]) + }); + + // Find and verify the destination resolve.root span + const destinationResolveRootSpan = findResolveRootSpan(destinationTrace); + expect(destinationResolveRootSpan).not.toBeNull(); + expect(destinationResolveRootSpan).toEqual({ + name: 'sveltekit.resolve.root', + status: { code: 0 }, + start_time: [expect.any(Number), expect.any(Number)], + end_time: [expect.any(Number), expect.any(Number)], + attributes: { + 'http.route': '/tracing/one/two/three/[...four]', + 'http.response.status_code': 200, + 'http.response.body.size': expect.stringMatching(/^\d+$/) + }, + links: [], + trace_id: destination_trace_id, + span_id: expect.any(String), + parent_span_id: expect.any(String), + children: [ + { + name: 'sveltekit.load', + status: { code: 0 }, + start_time: [expect.any(Number), expect.any(Number)], + end_time: [expect.any(Number), expect.any(Number)], + attributes: { + 'sveltekit.load.node_id': 'src/routes/+layout.server.js', + 'sveltekit.load.node_type': '+layout.server', + 'sveltekit.load.environment': 'server', + 'http.route': '/tracing/one/two/three/[...four]' + }, + links: [], + trace_id: destination_trace_id, + span_id: expect.any(String), + parent_span_id: expect.any(String), + children: [] + }, + { + name: 'sveltekit.load', + status: { code: 0 }, + start_time: [expect.any(Number), expect.any(Number)], + end_time: [expect.any(Number), expect.any(Number)], + attributes: { + 'sveltekit.load.node_id': 'src/routes/+layout.js', + 'sveltekit.load.node_type': '+layout', + 'sveltekit.load.environment': 'server', + 'http.route': '/tracing/one/two/three/[...four]' + }, + links: [], + trace_id: destination_trace_id, + span_id: expect.any(String), + parent_span_id: expect.any(String), + children: [] + } + ] + }); + }); + + test('correct spans are created for regular Error', async ({ page, read_traces }) => { + const test_id = rand(); + const response = await page.goto(`/tracing/regular-error?test_id=${test_id}`); + expect(response?.status()).toBe(500); + + const traces = read_traces(test_id); + const trace_id = traces[0].trace_id; + const trace = traces[0]; + + // Verify root span structure + expect(trace).toEqual({ + name: 'sveltekit.handle.root', + status: { code: 0 }, + start_time: [expect.any(Number), expect.any(Number)], + end_time: [expect.any(Number), expect.any(Number)], + attributes: { + 'http.route': '/tracing/regular-error', + 'http.method': 'GET', + 'http.url': expect.stringContaining(`/tracing/regular-error?test_id=${test_id}`), + 'sveltekit.is_data_request': false, + 'sveltekit.is_sub_request': false, + test_id + }, + links: [], + trace_id, + span_id: expect.any(String), + children: expect.arrayContaining([ + expect.objectContaining({ + name: 'sveltekit.handle.child', + attributes: expect.objectContaining({ + 'sveltekit.handle.child.index': 0 + }) + }) + ]) + }); + + // Find and verify the resolve.root span + const resolveRootSpan = findResolveRootSpan(trace); + expect(resolveRootSpan).not.toBeNull(); + expect(resolveRootSpan).toEqual({ + name: 'sveltekit.resolve.root', + status: { code: 0 }, + start_time: [expect.any(Number), expect.any(Number)], + end_time: [expect.any(Number), expect.any(Number)], + attributes: { + 'http.route': '/tracing/regular-error', + 'http.response.status_code': 500, + 'http.response.body.size': expect.stringMatching(/^\d+$/) + }, + links: [], + trace_id, + span_id: expect.any(String), + parent_span_id: expect.any(String), + children: expect.arrayContaining([ + expect.objectContaining({ + name: 'sveltekit.load', + status: { code: 2, message: 'Regular error from tracing test' }, + attributes: expect.objectContaining({ + 'sveltekit.load.node_id': 'src/routes/tracing/regular-error/+page.server.js', + 'sveltekit.load.result.type': 'unknown_error' + }) + }) + ]) + }); + }); + + test('correct spans are created for non-error object', async ({ page, read_traces }) => { + const test_id = rand(); + const response = await page.goto(`/tracing/non-error-object?test_id=${test_id}`); + expect(response?.status()).toBe(500); + + const traces = read_traces(test_id); + const trace_id = traces[0].trace_id; + const trace = traces[0]; + + // Verify root span structure + expect(trace).toEqual({ + name: 'sveltekit.handle.root', + status: { code: 0 }, + start_time: [expect.any(Number), expect.any(Number)], + end_time: [expect.any(Number), expect.any(Number)], + attributes: { + 'http.route': '/tracing/non-error-object', + 'http.method': 'GET', + 'http.url': expect.stringContaining(`/tracing/non-error-object?test_id=${test_id}`), + 'sveltekit.is_data_request': false, + 'sveltekit.is_sub_request': false, + test_id + }, + links: [], + trace_id, + span_id: expect.any(String), + children: expect.arrayContaining([ + expect.objectContaining({ + name: 'sveltekit.handle.child', + attributes: expect.objectContaining({ + 'sveltekit.handle.child.index': 0 + }) + }) + ]) + }); + + // Find and verify the resolve.root span + const resolveRootSpan = findResolveRootSpan(trace); + expect(resolveRootSpan).not.toBeNull(); + expect(resolveRootSpan).toEqual({ + name: 'sveltekit.resolve.root', + status: { code: 0 }, + start_time: [expect.any(Number), expect.any(Number)], + end_time: [expect.any(Number), expect.any(Number)], + attributes: { + 'http.route': '/tracing/non-error-object', + 'http.response.status_code': 500, + 'http.response.body.size': expect.stringMatching(/^\d+$/) + }, + links: [], + trace_id, + span_id: expect.any(String), + parent_span_id: expect.any(String), + children: expect.arrayContaining([ + expect.objectContaining({ + name: 'sveltekit.load', + status: { code: 2 }, + attributes: expect.objectContaining({ + 'sveltekit.load.node_id': 'src/routes/tracing/non-error-object/+page.server.js', + 'sveltekit.load.result.type': 'unknown_error' + }) + }) + ]) + }); + }); +}); diff --git a/packages/kit/test/types.d.ts b/packages/kit/test/types.d.ts new file mode 100644 index 000000000000..24083ce19bf3 --- /dev/null +++ b/packages/kit/test/types.d.ts @@ -0,0 +1,21 @@ +export interface SpanData { + name: string; + status: { + code: number; + message?: string; + }; + start_time: [number, number]; // HrTime tuple: [seconds, nanoseconds] + end_time: [number, number]; // HrTime tuple: [seconds, nanoseconds] + attributes: Record>; + links: Array<{ + context: any; + attributes?: Record>; + }>; + trace_id: string; + span_id: string; + parent_span_id: string | undefined; +} + +export type SpanTree = Omit & { + children: SpanTree[]; +}; diff --git a/packages/kit/test/utils.d.ts b/packages/kit/test/utils.d.ts index de03974f5baa..95a3f7f11c21 100644 --- a/packages/kit/test/utils.d.ts +++ b/packages/kit/test/utils.d.ts @@ -10,6 +10,7 @@ import { import { IncomingMessage, ServerResponse } from 'node:http'; import '../types/index'; import { AfterNavigate, BeforeNavigate } from '@sveltejs/kit'; +import { SpanTree } from './types'; export const test: TestType< PlaywrightTestArgs & @@ -30,6 +31,7 @@ export const test: TestType< * `handleError` defines the shape */ read_errors(href: string): Record; + read_traces(test_id: string): SpanTree[]; start_server( handler: (req: IncomingMessage, res: ServerResponse) => void ): Promise<{ port: number }>; diff --git a/packages/kit/test/utils.js b/packages/kit/test/utils.js index e7c84a51069c..eba4a5fd1a03 100644 --- a/packages/kit/test/utils.js +++ b/packages/kit/test/utils.js @@ -1,3 +1,4 @@ +/** @import {SpanData, SpanTree} from './types' */ import fs from 'node:fs'; import http from 'node:http'; import path from 'node:path'; @@ -144,6 +145,27 @@ export const test = base.extend({ await use(read_errors); }, + // eslint-disable-next-line no-empty-pattern -- Playwright doesn't let us use `_` as a parameter name. It must be a destructured object + read_traces: async ({}, use) => { + /** @param {string} test_id */ + function read_traces(test_id) { + const raw = fs.readFileSync('test/spans.jsonl', 'utf8').split('\n').filter(Boolean); + const traces = /** @type {SpanData[]} */ (raw.map((line) => JSON.parse(line))); + const root_traces = traces.filter( + (trace) => trace.parent_span_id === undefined && trace.attributes.test_id === test_id + ); + if (root_traces.length === 0) { + return []; + } + return root_traces.map((root_trace) => { + const child_traces = traces.filter((span) => span.trace_id === root_trace.trace_id); + return build_span_tree(root_trace, child_traces); + }); + } + + await use(read_traces); + }, + // eslint-disable-next-line no-empty-pattern -- Playwright doesn't let us use `_` as a parameter name. It must be a destructured object start_server: async ({}, use) => { /** @@ -288,3 +310,16 @@ export const config = { testDir: 'test', testMatch: /(.+\.)?(test|spec)\.[jt]s/ }; + +/** + * @param {SpanData} current_span + * @param {SpanData[]} child_spans + * @returns {SpanTree} + */ +function build_span_tree(current_span, child_spans) { + const children = child_spans.filter((span) => span.parent_span_id === current_span.span_id); + return { + ...current_span, + children: children.map((child) => build_span_tree(child, child_spans)) + }; +} diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 28a0b6c4a56a..9aca4624bbf5 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -3,6 +3,7 @@ declare module '@sveltejs/kit' { import type { SvelteConfig } from '@sveltejs/vite-plugin-svelte'; + import type { Span } from '@opentelemetry/api'; /** * [Adapters](https://svelte.dev/docs/kit/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. */ @@ -383,6 +384,15 @@ declare module '@sveltejs/kit' { */ privatePrefix?: string; }; + /** Experimental features. Here be dragons. Breaking changes may occur in minor releases. */ + experimental?: { + /** + * Whether to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), and [form actions](https://svelte.dev/docs/kit/form-actions). + * @default undefined + * @since 2.26.0 // TODO: update this before publishing + */ + tracing?: 'server'; + }; /** * Where to find various files within your project. */ @@ -949,6 +959,17 @@ declare module '@sveltejs/kit' { * ``` */ untrack: (fn: () => T) => T; + + /** + * Access to spans for tracing. If tracing is not enabled or the function is being run in the browser, these spans will do nothing.\ + * @since 2.26.0 // TODO: update this before publishing + */ + tracing: { + /** The root span for the request. This span is named `sveltekit.handle.root`. */ + rootSpan: Span; + /** The span associated with the current `load` function. */ + currentSpan: Span; + }; } export interface NavigationEvent< @@ -1224,6 +1245,17 @@ declare module '@sveltejs/kit' { * `true` for `+server.js` calls coming from SvelteKit without the overhead of actually making an HTTP request. This happens when you make same-origin `fetch` requests on the server. */ isSubRequest: boolean; + + /** + * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. + * @since 2.26.0 // TODO: update this before publishing + */ + tracing: { + /** The root span for the request. This span is named `sveltekit.handle.root`. */ + rootSpan: Span; + /** The span associated with the current `handle` hook, `load` function, or form action. */ + currentSpan: Span; + }; } /** @@ -1380,6 +1412,17 @@ declare module '@sveltejs/kit' { * ``` */ untrack: (fn: () => T) => T; + + /** + * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. + * @since 2.26.0 // TODO: update this before publishing + */ + tracing: { + /** The root span for the request. This span is named `sveltekit.handle.root`. */ + rootSpan: Span; + /** The span associated with the current server `load` function. */ + currentSpan: Span; + }; } /** @@ -2049,6 +2092,7 @@ declare module '@sveltejs/kit' { } declare module '@sveltejs/kit/hooks' { + import type { Handle } from '@sveltejs/kit'; /** * A helper function for sequencing multiple `handle` calls in a middleware-like manner. * The behavior for the `handle` options is as follows: @@ -2119,7 +2163,7 @@ declare module '@sveltejs/kit/hooks' { * * @param handlers The chain of `handle` functions * */ - export function sequence(...handlers: import("@sveltejs/kit").Handle[]): import("@sveltejs/kit").Handle; + export function sequence(...handlers: Handle[]): Handle; export {}; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8ed9775338ca..fbb60debb4a6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -526,6 +526,15 @@ importers: packages/kit/test/apps/basics: devDependencies: + '@opentelemetry/api': + specifier: ^1.9.0 + version: 1.9.0 + '@opentelemetry/sdk-node': + specifier: ^0.203.0 + version: 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-node': + specifier: ^2.0.1 + version: 2.0.1(@opentelemetry/api@1.9.0) '@sveltejs/kit': specifier: workspace:^ version: link:../../.. @@ -1822,6 +1831,15 @@ packages: '@fontsource/libre-barcode-128-text@5.1.0': resolution: {integrity: sha512-MC7foQFRT0NDcsqBWQua2T3gs/fh/uTowTxfoPqGQWjqroiMxRZhQh7jerjnpcI+Xi3yR5bwCo6W2uwCza1FRw==} + '@grpc/grpc-js@1.13.4': + resolution: {integrity: sha512-GsFaMXCkMqkKIvwCQjCrwH+GHbPKBjhwo/8ZuUkWHqbI73Kky9I+pQltrlT0+MWpedCoosda53lgjYfyEPgxBg==} + engines: {node: '>=12.10.0'} + + '@grpc/proto-loader@0.7.15': + resolution: {integrity: sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==} + engines: {node: '>=6'} + hasBin: true + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -2099,6 +2117,9 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@js-sdsl/ordered-map@4.4.2': + resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + '@lukeed/ms@2.0.2': resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==} engines: {node: '>=8'} @@ -2370,6 +2391,10 @@ packages: '@octokit/types@14.1.0': resolution: {integrity: sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g==} + '@opentelemetry/api-logs@0.203.0': + resolution: {integrity: sha512-9B9RU0H7Ya1Dx/Rkyc4stuBZSGVQF27WigitInx2QQoj6KUpEFYPKoWjdFTunJYxmXmh17HeBvbMa1EhGyPmqQ==} + engines: {node: '>=8.0.0'} + '@opentelemetry/api@1.8.0': resolution: {integrity: sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==} engines: {node: '>=8.0.0'} @@ -2378,6 +2403,160 @@ packages: resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} engines: {node: '>=8.0.0'} + '@opentelemetry/context-async-hooks@2.0.1': + resolution: {integrity: sha512-XuY23lSI3d4PEqKA+7SLtAgwqIfc6E/E9eAQWLN1vlpC53ybO3o6jW4BsXo1xvz9lYyyWItfQDDLzezER01mCw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/core@2.0.1': + resolution: {integrity: sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/exporter-logs-otlp-grpc@0.203.0': + resolution: {integrity: sha512-g/2Y2noc/l96zmM+g0LdeuyYKINyBwN6FJySoU15LHPLcMN/1a0wNk2SegwKcxrRdE7Xsm7fkIR5n6XFe3QpPw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-logs-otlp-http@0.203.0': + resolution: {integrity: sha512-s0hys1ljqlMTbXx2XiplmMJg9wG570Z5lH7wMvrZX6lcODI56sG4HL03jklF63tBeyNwK2RV1/ntXGo3HgG4Qw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-logs-otlp-proto@0.203.0': + resolution: {integrity: sha512-nl/7S91MXn5R1aIzoWtMKGvqxgJgepB/sH9qW0rZvZtabnsjbf8OQ1uSx3yogtvLr0GzwD596nQKz2fV7q2RBw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-metrics-otlp-grpc@0.203.0': + resolution: {integrity: sha512-FCCj9nVZpumPQSEI57jRAA89hQQgONuoC35Lt+rayWY/mzCAc6BQT7RFyFaZKJ2B7IQ8kYjOCPsF/HGFWjdQkQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-metrics-otlp-http@0.203.0': + resolution: {integrity: sha512-HFSW10y8lY6BTZecGNpV3GpoSy7eaO0Z6GATwZasnT4bEsILp8UJXNG5OmEsz4SdwCSYvyCbTJdNbZP3/8LGCQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-metrics-otlp-proto@0.203.0': + resolution: {integrity: sha512-OZnhyd9npU7QbyuHXFEPVm3LnjZYifuKpT3kTnF84mXeEQ84pJJZgyLBpU4FSkSwUkt/zbMyNAI7y5+jYTWGIg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-prometheus@0.203.0': + resolution: {integrity: sha512-2jLuNuw5m4sUj/SncDf/mFPabUxMZmmYetx5RKIMIQyPnl6G6ooFzfeE8aXNRf8YD1ZXNlCnRPcISxjveGJHNg==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-trace-otlp-grpc@0.203.0': + resolution: {integrity: sha512-322coOTf81bm6cAA8+ML6A+m4r2xTCdmAZzGNTboPXRzhwPt4JEmovsFAs+grpdarObd68msOJ9FfH3jxM6wqA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-trace-otlp-http@0.203.0': + resolution: {integrity: sha512-ZDiaswNYo0yq/cy1bBLJFe691izEJ6IgNmkjm4C6kE9ub/OMQqDXORx2D2j8fzTBTxONyzusbaZlqtfmyqURPw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-trace-otlp-proto@0.203.0': + resolution: {integrity: sha512-1xwNTJ86L0aJmWRwENCJlH4LULMG2sOXWIVw+Szta4fkqKVY50Eo4HoVKKq6U9QEytrWCr8+zjw0q/ZOeXpcAQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/exporter-zipkin@2.0.1': + resolution: {integrity: sha512-a9eeyHIipfdxzCfc2XPrE+/TI3wmrZUDFtG2RRXHSbZZULAny7SyybSvaDvS77a7iib5MPiAvluwVvbGTsHxsw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.0.0 + + '@opentelemetry/instrumentation@0.203.0': + resolution: {integrity: sha512-ke1qyM+3AK2zPuBPb6Hk/GCsc5ewbLvPNkEuELx/JmANeEp6ZjnZ+wypPAJSucTw0wvCGrUaibDSdcrGFoWxKQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/otlp-exporter-base@0.203.0': + resolution: {integrity: sha512-Wbxf7k+87KyvxFr5D7uOiSq/vHXWommvdnNE7vECO3tAhsA2GfOlpWINCMWUEPdHZ7tCXxw6Epp3vgx3jU7llQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/otlp-grpc-exporter-base@0.203.0': + resolution: {integrity: sha512-te0Ze1ueJF+N/UOFl5jElJW4U0pZXQ8QklgSfJ2linHN0JJsuaHG8IabEUi2iqxY8ZBDlSiz1Trfv5JcjWWWwQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/otlp-transformer@0.203.0': + resolution: {integrity: sha512-Y8I6GgoCna0qDQ2W6GCRtaF24SnvqvA8OfeTi7fqigD23u8Jpb4R5KFv/pRvrlGagcCLICMIyh9wiejp4TXu/A==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': ^1.3.0 + + '@opentelemetry/propagator-b3@2.0.1': + resolution: {integrity: sha512-Hc09CaQ8Tf5AGLmf449H726uRoBNGPBL4bjr7AnnUpzWMvhdn61F78z9qb6IqB737TffBsokGAK1XykFEZ1igw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/propagator-jaeger@2.0.1': + resolution: {integrity: sha512-7PMdPBmGVH2eQNb/AtSJizQNgeNTfh6jQFqys6lfhd6P4r+m/nTh3gKPPpaCXVdRQ+z93vfKk+4UGty390283w==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/resources@2.0.1': + resolution: {integrity: sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/sdk-logs@0.203.0': + resolution: {integrity: sha512-vM2+rPq0Vi3nYA5akQD2f3QwossDnTDLvKbea6u/A2NZ3XDkPxMfo/PNrDoXhDUD/0pPo2CdH5ce/thn9K0kLw==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.4.0 <1.10.0' + + '@opentelemetry/sdk-metrics@2.0.1': + resolution: {integrity: sha512-wf8OaJoSnujMAHWR3g+/hGvNcsC16rf9s1So4JlMiFaFHiE4HpIA3oUh+uWZQ7CNuK8gVW/pQSkgoa5HkkOl0g==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.9.0 <1.10.0' + + '@opentelemetry/sdk-node@0.203.0': + resolution: {integrity: sha512-zRMvrZGhGVMvAbbjiNQW3eKzW/073dlrSiAKPVWmkoQzah9wfynpVPeL55f9fVIm0GaBxTLcPeukWGy0/Wj7KQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/sdk-trace-base@2.0.1': + resolution: {integrity: sha512-xYLlvk/xdScGx1aEqvxLwf6sXQLXCjk3/1SQT9X9AoN5rXRhkdvIFShuNNmtTEPRBqcsMbS4p/gJLNI2wXaDuQ==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.3.0 <1.10.0' + + '@opentelemetry/sdk-trace-node@2.0.1': + resolution: {integrity: sha512-UhdbPF19pMpBtCWYP5lHbTogLWx9N0EBxtdagvkn5YtsAnCBZzL7SjktG+ZmupRgifsHMjwUaCCaVmqGfSADmA==} + engines: {node: ^18.19.0 || >=20.6.0} + peerDependencies: + '@opentelemetry/api': '>=1.0.0 <1.10.0' + + '@opentelemetry/semantic-conventions@1.36.0': + resolution: {integrity: sha512-TtxJSRD8Ohxp6bKkhrm27JRHAxPczQA7idtcTOMYI+wQRRrfgqxHv1cFbCApcSnNjtXkmzFozn6jQtFrOmbjPQ==} + engines: {node: '>=14'} + '@parcel/watcher-android-arm64@2.5.1': resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} engines: {node: '>= 10.0.0'} @@ -2494,6 +2673,36 @@ packages: '@polka/url@1.0.0-next.28': resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.4': + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + '@publint/pack@0.1.0': resolution: {integrity: sha512-NvV5jPAQIMCoHvaJ0ZhfouBJ2woFYYf+o6B7dCHGh/tLKSPVoxhjffi35xPuMHgOv65aTOKUzML5XwQF9EkDAA==} engines: {node: '>=18'} @@ -3429,6 +3638,9 @@ packages: citty@0.1.6: resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + cjs-module-lexer@1.4.3: + resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + clean-deep@3.4.0: resolution: {integrity: sha512-Lo78NV5ItJL/jl+B5w0BycAisaieJGXK1qYi/9m4SjR8zbqmrUtO7Yhro40wEShGmmxs/aJLI/A+jNhdkXK8mw==} engines: {node: '>=4'} @@ -4605,6 +4817,9 @@ packages: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} + import-in-the-middle@1.14.2: + resolution: {integrity: sha512-5tCuY9BV8ujfOpwtAGgsTx9CGUapcFMEEyByLv1B+v2+6DhAcw+Zr0nhQT7uwaZ7DiourxFEscghOR8e1aPLQw==} + imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -5015,6 +5230,9 @@ packages: lodash-es@4.17.21: resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} @@ -5070,6 +5288,9 @@ packages: resolution: {integrity: sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==} engines: {node: '>= 12.0.0'} + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + loupe@3.1.3: resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} @@ -5245,6 +5466,9 @@ packages: engines: {node: '>=18'} hasBin: true + module-details-from-path@1.0.4: + resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} + moize@6.1.6: resolution: {integrity: sha512-vSKdIUO61iCmTqhdoIDrqyrtp87nWZUmBPniNjO0fX49wEYmyDO4lvlnFXiGcaH1JLE/s/9HbiK4LSHsbiUY6Q==} @@ -5796,6 +6020,10 @@ packages: proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + protobufjs@7.5.3: + resolution: {integrity: sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==} + engines: {node: '>=12.0.0'} + proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -5943,6 +6171,10 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + require-in-the-middle@7.5.2: + resolution: {integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==} + engines: {node: '>=8.6.0'} + require-package-name@2.0.1: resolution: {integrity: sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==} @@ -7547,6 +7779,18 @@ snapshots: '@fontsource/libre-barcode-128-text@5.1.0': {} + '@grpc/grpc-js@1.13.4': + dependencies: + '@grpc/proto-loader': 0.7.15 + '@js-sdsl/ordered-map': 4.4.2 + + '@grpc/proto-loader@0.7.15': + dependencies: + lodash.camelcase: 4.3.0 + long: 5.3.2 + protobufjs: 7.5.3 + yargs: 17.7.2 + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.6': @@ -7759,6 +8003,8 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@js-sdsl/ordered-map@4.4.2': {} + '@lukeed/ms@2.0.2': {} '@manypkg/find-root@1.1.0': @@ -8315,10 +8561,235 @@ snapshots: dependencies: '@octokit/openapi-types': 25.1.0 + '@opentelemetry/api-logs@0.203.0': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api@1.8.0': {} '@opentelemetry/api@1.9.0': {} + '@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + + '@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/semantic-conventions': 1.36.0 + + '@opentelemetry/exporter-logs-otlp-grpc@0.203.0(@opentelemetry/api@1.9.0)': + dependencies: + '@grpc/grpc-js': 1.13.4 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.203.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-logs-otlp-http@0.203.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.203.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.203.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-logs-otlp-proto@0.203.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.203.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-metrics-otlp-grpc@0.203.0(@opentelemetry/api@1.9.0)': + dependencies: + '@grpc/grpc-js': 1.13.4 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-metrics-otlp-http@0.203.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-metrics-otlp-proto@0.203.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-prometheus@0.203.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-trace-otlp-grpc@0.203.0(@opentelemetry/api@1.9.0)': + dependencies: + '@grpc/grpc-js': 1.13.4 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-trace-otlp-http@0.203.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/exporter-zipkin@2.0.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.36.0 + + '@opentelemetry/instrumentation@0.203.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.203.0 + import-in-the-middle: 1.14.2 + require-in-the-middle: 7.5.2 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/otlp-exporter-base@0.203.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/otlp-grpc-exporter-base@0.203.0(@opentelemetry/api@1.9.0)': + dependencies: + '@grpc/grpc-js': 1.13.4 + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + + '@opentelemetry/otlp-transformer@0.203.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.203.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) + protobufjs: 7.5.3 + + '@opentelemetry/propagator-b3@2.0.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/propagator-jaeger@2.0.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/resources@2.0.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.36.0 + + '@opentelemetry/sdk-logs@0.203.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.203.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/sdk-metrics@2.0.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/sdk-node@0.203.0(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/api-logs': 0.203.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-grpc': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-http': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-proto': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-grpc': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-proto': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-prometheus': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-grpc': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-http': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-proto': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-zipkin': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-b3': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-jaeger': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-node': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.36.0 + transitivePeerDependencies: + - supports-color + + '@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.36.0 + + '@opentelemetry/sdk-trace-node@2.0.1(@opentelemetry/api@1.9.0)': + dependencies: + '@opentelemetry/api': 1.9.0 + '@opentelemetry/context-async-hooks': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) + + '@opentelemetry/semantic-conventions@1.36.0': {} + '@parcel/watcher-android-arm64@2.5.1': optional: true @@ -8414,6 +8885,29 @@ snapshots: '@polka/url@1.0.0-next.28': {} + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.4': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.0': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.0': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.0': {} + '@publint/pack@0.1.0': {} '@rollup/plugin-commonjs@28.0.1(rollup@4.40.1)': @@ -9064,6 +9558,10 @@ snapshots: dependencies: acorn: 8.14.1 + acorn-import-attributes@1.9.5(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -9415,6 +9913,8 @@ snapshots: dependencies: consola: 3.2.3 + cjs-module-lexer@1.4.3: {} + clean-deep@3.4.0: dependencies: lodash.isempty: 4.4.0 @@ -10680,6 +11180,13 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 + import-in-the-middle@1.14.2: + dependencies: + acorn: 8.15.0 + acorn-import-attributes: 1.9.5(acorn@8.15.0) + cjs-module-lexer: 1.4.3 + module-details-from-path: 1.0.4 + imurmurhash@0.1.4: {} indent-string@5.0.0: {} @@ -11076,6 +11583,8 @@ snapshots: lodash-es@4.17.21: {} + lodash.camelcase@4.3.0: {} + lodash.debounce@4.0.8: {} lodash.includes@4.3.0: {} @@ -11131,6 +11640,8 @@ snapshots: safe-stable-stringify: 2.5.0 triple-beam: 1.4.1 + long@5.3.2: {} + loupe@3.1.3: {} lower-case@2.0.2: @@ -11274,6 +11785,8 @@ snapshots: ast-module-types: 6.0.1 node-source-walk: 7.0.1 + module-details-from-path@1.0.4: {} + moize@6.1.6: dependencies: fast-equals: 3.0.3 @@ -11912,6 +12425,21 @@ snapshots: proto-list@1.2.4: {} + protobufjs@7.5.3: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 18.19.119 + long: 5.3.2 + proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 @@ -12068,6 +12596,14 @@ snapshots: require-from-string@2.0.2: {} + require-in-the-middle@7.5.2: + dependencies: + debug: 4.4.1(supports-color@10.0.0) + module-details-from-path: 1.0.4 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + require-package-name@2.0.1: {} requires-port@1.0.0: {} From f65b78f065e848da227999a6c5935f10571c8afc Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Wed, 23 Jul 2025 10:46:26 -0600 Subject: [PATCH 03/74] Update packages/kit/src/exports/public.d.ts Co-authored-by: Rich Harris --- packages/kit/src/exports/public.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index d98f1fb11786..8d4508cb2607 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -979,7 +979,7 @@ export interface LoadEvent< untrack: (fn: () => T) => T; /** - * Access to spans for tracing. If tracing is not enabled or the function is being run in the browser, these spans will do nothing.\ + * Access to spans for tracing. If tracing is not enabled or the function is being run in the browser, these spans will do nothing. * @since 2.26.0 // TODO: update this before publishing */ tracing: { From 77d447f9328c502de94363f93d11f3395b0ce9b4 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Wed, 23 Jul 2025 12:03:23 -0600 Subject: [PATCH 04/74] chore: Switch to `tracing: { server: boolean }` --- packages/kit/src/core/config/index.spec.js | 24 +++++++++++++------ packages/kit/src/core/config/options.js | 7 ++---- packages/kit/src/core/sync/write_server.js | 2 +- packages/kit/src/exports/public.d.ts | 6 +++-- .../kit/test/apps/basics/svelte.config.js | 2 +- packages/kit/types/index.d.ts | 8 ++++--- 6 files changed, 30 insertions(+), 19 deletions(-) diff --git a/packages/kit/src/core/config/index.spec.js b/packages/kit/src/core/config/index.spec.js index d1a954ac2f87..97236c1492a4 100644 --- a/packages/kit/src/core/config/index.spec.js +++ b/packages/kit/src/core/config/index.spec.js @@ -77,7 +77,7 @@ const get_defaults = (prefix = '') => ({ privatePrefix: '' }, experimental: { - tracing: undefined + tracing: { server: false } }, files: { assets: join(prefix, 'static'), @@ -413,7 +413,17 @@ test('accepts valid tracing values', () => { validate_config({ kit: { experimental: { - tracing: 'server' + tracing: { server: true } + } + } + }); + }); + + assert.doesNotThrow(() => { + validate_config({ + kit: { + experimental: { + tracing: { server: false } } } }); @@ -440,27 +450,27 @@ test('errors on invalid tracing values', () => { } } }); - }, /^config\.kit\.experimental\.tracing should be undefined or "server"$/); + }, /^config\.kit\.experimental\.tracing should be an object$/); assert.throws(() => { validate_config({ kit: { experimental: { // @ts-expect-error - given value expected to throw - tracing: false + tracing: 'server' } } }); - }, /^config\.kit\.experimental\.tracing should be undefined or "server"$/); + }, /^config\.kit\.experimental\.tracing should be an object$/); assert.throws(() => { validate_config({ kit: { experimental: { // @ts-expect-error - given value expected to throw - tracing: 'client' + tracing: { server: 'invalid' } } } }); - }, /^config\.kit\.experimental\.tracing should be undefined or "server"$/); + }, /^config\.kit\.experimental\.tracing\.server should be true or false, if specified$/); }); diff --git a/packages/kit/src/core/config/options.js b/packages/kit/src/core/config/options.js index cd937a5af528..88d2eedcc2f3 100644 --- a/packages/kit/src/core/config/options.js +++ b/packages/kit/src/core/config/options.js @@ -121,11 +121,8 @@ const options = object( }), experimental: object({ - tracing: validate(undefined, (input, keypath) => { - if (input !== 'server') { - throw new Error(`${keypath} should be undefined or "server"`); - } - return input; + tracing: object({ + server: boolean(false) }) }), diff --git a/packages/kit/src/core/sync/write_server.js b/packages/kit/src/core/sync/write_server.js index a2d6f3b99eb3..0bc4be558779 100644 --- a/packages/kit/src/core/sync/write_server.js +++ b/packages/kit/src/core/sync/write_server.js @@ -35,7 +35,7 @@ import { set_manifest, set_read_implementation } from '__sveltekit/server'; import { set_private_env, set_public_env, set_safe_public_env } from '${runtime_directory}/shared-server.js'; import { get_tracer, enable_tracing } from '${runtime_directory}/telemetry/get_tracer.js'; -if (${s(config.kit.experimental.tracing === 'server')}) { +if (${s(config.kit.experimental.tracing.server)}) { enable_tracing(); } diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 8d4508cb2607..8f1d76408689 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -406,10 +406,12 @@ export interface KitConfig { experimental?: { /** * Whether to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), and [form actions](https://svelte.dev/docs/kit/form-actions). - * @default undefined + * @default { server: false } * @since 2.26.0 // TODO: update this before publishing */ - tracing?: 'server'; + tracing?: { + server?: boolean; + }; }; /** * Where to find various files within your project. diff --git a/packages/kit/test/apps/basics/svelte.config.js b/packages/kit/test/apps/basics/svelte.config.js index 12f8ebb08a6b..2f73d099e5ea 100644 --- a/packages/kit/test/apps/basics/svelte.config.js +++ b/packages/kit/test/apps/basics/svelte.config.js @@ -42,7 +42,7 @@ const config = { resolution: /** @type {'client' | 'server'} */ (process.env.ROUTER_RESOLUTION) || 'client' }, - experimental: { tracing: 'server' } + experimental: { tracing: { server: true } } } }; diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 9aca4624bbf5..2a7ea0168da6 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -388,10 +388,12 @@ declare module '@sveltejs/kit' { experimental?: { /** * Whether to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), and [form actions](https://svelte.dev/docs/kit/form-actions). - * @default undefined + * @default { server: false } * @since 2.26.0 // TODO: update this before publishing */ - tracing?: 'server'; + tracing?: { + server?: boolean; + }; }; /** * Where to find various files within your project. @@ -961,7 +963,7 @@ declare module '@sveltejs/kit' { untrack: (fn: () => T) => T; /** - * Access to spans for tracing. If tracing is not enabled or the function is being run in the browser, these spans will do nothing.\ + * Access to spans for tracing. If tracing is not enabled or the function is being run in the browser, these spans will do nothing. * @since 2.26.0 // TODO: update this before publishing */ tracing: { From 965bfea9d594856a09a6a0183884f3374485a584 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Wed, 23 Jul 2025 17:12:58 -0600 Subject: [PATCH 05/74] chore: Make enablement / importing of otel make more sense --- packages/kit/kit.vitest.config.js | 3 + packages/kit/src/core/sync/write_server.js | 6 -- packages/kit/src/exports/hooks/sequence.js | 5 +- packages/kit/src/exports/vite/index.js | 6 +- packages/kit/src/runtime/server/data/index.js | 1 - .../kit/src/runtime/server/page/actions.js | 12 +-- packages/kit/src/runtime/server/page/index.js | 8 +- .../kit/src/runtime/server/page/load_data.js | 9 +- .../runtime/server/page/respond_with_error.js | 5 +- packages/kit/src/runtime/server/respond.js | 4 - .../kit/src/runtime/telemetry/get_tracer.js | 38 -------- .../src/runtime/telemetry/get_tracer.spec.js | 34 ------- .../kit/src/runtime/telemetry/load_otel.js | 18 ---- .../runtime/telemetry/otel.disabled.spec.js | 10 +++ .../runtime/telemetry/otel.enabled.spec.js | 10 +++ packages/kit/src/runtime/telemetry/otel.js | 18 ++++ .../runtime/telemetry/otel.missing.spec.js | 15 ++++ .../telemetry/record_span.disabled.spec.js | 15 ++++ ...an.spec.js => record_span.enabled.spec.js} | 88 ++++++++----------- .../kit/src/runtime/telemetry/record_span.js | 17 ++-- packages/kit/src/types/global-private.d.ts | 2 + packages/kit/src/types/internal.d.ts | 2 - 22 files changed, 132 insertions(+), 194 deletions(-) delete mode 100644 packages/kit/src/runtime/telemetry/get_tracer.js delete mode 100644 packages/kit/src/runtime/telemetry/get_tracer.spec.js delete mode 100644 packages/kit/src/runtime/telemetry/load_otel.js create mode 100644 packages/kit/src/runtime/telemetry/otel.disabled.spec.js create mode 100644 packages/kit/src/runtime/telemetry/otel.enabled.spec.js create mode 100644 packages/kit/src/runtime/telemetry/otel.js create mode 100644 packages/kit/src/runtime/telemetry/otel.missing.spec.js create mode 100644 packages/kit/src/runtime/telemetry/record_span.disabled.spec.js rename packages/kit/src/runtime/telemetry/{record_span.spec.js => record_span.enabled.spec.js} (64%) diff --git a/packages/kit/kit.vitest.config.js b/packages/kit/kit.vitest.config.js index aa93595569df..f443a76ae109 100644 --- a/packages/kit/kit.vitest.config.js +++ b/packages/kit/kit.vitest.config.js @@ -3,6 +3,9 @@ import { defineConfig } from 'vitest/config'; // this file needs a custom name so that the numerous test subprojects don't all pick it up export default defineConfig({ + define: { + __SVELTEKIT_SERVER_TRACING_ENABLED__: false + }, server: { watch: { ignored: ['**/node_modules/**', '**/.svelte-kit/**'] diff --git a/packages/kit/src/core/sync/write_server.js b/packages/kit/src/core/sync/write_server.js index 0bc4be558779..5e93d5c1cd25 100644 --- a/packages/kit/src/core/sync/write_server.js +++ b/packages/kit/src/core/sync/write_server.js @@ -33,11 +33,6 @@ import { set_building, set_prerendering } from '__sveltekit/environment'; import { set_assets } from '__sveltekit/paths'; import { set_manifest, set_read_implementation } from '__sveltekit/server'; import { set_private_env, set_public_env, set_safe_public_env } from '${runtime_directory}/shared-server.js'; -import { get_tracer, enable_tracing } from '${runtime_directory}/telemetry/get_tracer.js'; - -if (${s(config.kit.experimental.tracing.server)}) { - enable_tracing(); -} export const options = { app_template_contains_nonce: ${template.includes('%sveltekit.nonce%')}, @@ -65,7 +60,6 @@ export const options = { .replace(/%sveltekit\.status%/g, '" + status + "') .replace(/%sveltekit\.error\.message%/g, '" + message + "')} }, - tracer: get_tracer(), version_hash: ${s(hash(config.kit.version.name))} }; diff --git a/packages/kit/src/exports/hooks/sequence.js b/packages/kit/src/exports/hooks/sequence.js index 443be6c24cd4..4cb55bb890a6 100644 --- a/packages/kit/src/exports/hooks/sequence.js +++ b/packages/kit/src/exports/hooks/sequence.js @@ -1,7 +1,6 @@ /** @import { Handle, RequestEvent, ResolveOptions } from '@sveltejs/kit' */ /** @import { MaybePromise } from 'types' */ import { with_event } from '../../runtime/app/server/event.js'; -import { get_tracer } from '../../runtime/telemetry/get_tracer.js'; import { record_span } from '../../runtime/telemetry/record_span.js'; /** @@ -79,12 +78,11 @@ export function sequence(...handlers) { const length = handlers.length; if (!length) return ({ event, resolve }) => resolve(event); - return async ({ event, resolve }) => { + return ({ event, resolve }) => { // there's an assumption here that people aren't doing something insane like sequence(() => {}, sequence(() => {})) // worst case there is that future spans get a lower-down span as their root span -- the tracing would still work, // it'd just look a little weird const { rootSpan } = event.tracing; - const tracer = await get_tracer(); return apply_handle(0, event, {}); /** @@ -97,7 +95,6 @@ export function sequence(...handlers) { const handle = handlers[i]; return record_span({ - tracer, name: 'sveltekit.handle.child', attributes: { 'sveltekit.handle.child.index': i diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index a0b8f5c29cd0..467457b23760 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -323,7 +323,8 @@ async function kit({ svelte_config }) { __SVELTEKIT_APP_VERSION_POLL_INTERVAL__: s(kit.version.pollInterval), __SVELTEKIT_DEV__: 'false', __SVELTEKIT_EMBEDDED__: kit.embedded ? 'true' : 'false', - __SVELTEKIT_CLIENT_ROUTING__: kit.router.resolution === 'client' ? 'true' : 'false' + __SVELTEKIT_CLIENT_ROUTING__: kit.router.resolution === 'client' ? 'true' : 'false', + __SVELTEKIT_SERVER_TRACING_ENABLED__: kit.experimental.tracing.server ? 'true' : 'false' }; if (!secondary_build_started) { @@ -334,7 +335,8 @@ async function kit({ svelte_config }) { __SVELTEKIT_APP_VERSION_POLL_INTERVAL__: '0', __SVELTEKIT_DEV__: 'true', __SVELTEKIT_EMBEDDED__: kit.embedded ? 'true' : 'false', - __SVELTEKIT_CLIENT_ROUTING__: kit.router.resolution === 'client' ? 'true' : 'false' + __SVELTEKIT_CLIENT_ROUTING__: kit.router.resolution === 'client' ? 'true' : 'false', + __SVELTEKIT_SERVER_TRACING_ENABLED__: kit.experimental.tracing.server ? 'true' : 'false' }; // These Kit dependencies are packaged as CommonJS, which means they must always be externalized. diff --git a/packages/kit/src/runtime/server/data/index.js b/packages/kit/src/runtime/server/data/index.js index c63fc8654256..0c5d8f1d0ecf 100644 --- a/packages/kit/src/runtime/server/data/index.js +++ b/packages/kit/src/runtime/server/data/index.js @@ -63,7 +63,6 @@ export async function render_data( event: new_event, state, node, - tracer: await options.tracer, parent: async () => { /** @type {Record} */ const data = {}; diff --git a/packages/kit/src/runtime/server/page/actions.js b/packages/kit/src/runtime/server/page/actions.js index 3db90d24d740..4bdf3e932235 100644 --- a/packages/kit/src/runtime/server/page/actions.js +++ b/packages/kit/src/runtime/server/page/actions.js @@ -1,4 +1,3 @@ -/** @import { Tracer } from '@opentelemetry/api' */ /** @import { RequestEvent, ActionResult, Actions } from '@sveltejs/kit' */ /** @import { SSROptions, SSRNode, ServerNode, ServerHooks } from 'types' */ import * as devalue from 'devalue'; @@ -55,7 +54,7 @@ export async function handle_action_json_request(event, options, server) { check_named_default_separate(actions); try { - const data = await call_action(event, actions, await options.tracer); + const data = await call_action(event, actions); if (__SVELTEKIT_DEV__) { validate_action_return(data); @@ -143,10 +142,9 @@ export function is_action_request(event) { /** * @param {RequestEvent} event * @param {SSRNode['server'] | undefined} server - * @param {Tracer} tracer * @returns {Promise} */ -export async function handle_action_request(event, server, tracer) { +export async function handle_action_request(event, server) { const actions = server?.actions; if (!actions) { @@ -169,7 +167,7 @@ export async function handle_action_request(event, server, tracer) { check_named_default_separate(actions); try { - const data = await call_action(event, actions, tracer); + const data = await call_action(event, actions); if (__SVELTEKIT_DEV__) { validate_action_return(data); @@ -221,10 +219,9 @@ function check_named_default_separate(actions) { /** * @param {RequestEvent} event * @param {NonNullable} actions - * @param {Tracer} tracer * @throws {Redirect | HttpError | SvelteKitError | Error} */ -async function call_action(event, actions, tracer) { +async function call_action(event, actions) { const url = new URL(event.request.url); let name = 'default'; @@ -255,7 +252,6 @@ async function call_action(event, actions, tracer) { return record_span({ name: 'sveltekit.action', - tracer, attributes: { 'sveltekit.action.name': name, 'http.route': event.route.id || 'unknown' diff --git a/packages/kit/src/runtime/server/page/index.js b/packages/kit/src/runtime/server/page/index.js index 3283e836ef37..de17e7666b0d 100644 --- a/packages/kit/src/runtime/server/page/index.js +++ b/packages/kit/src/runtime/server/page/index.js @@ -56,7 +56,7 @@ export async function render_page(event, page, options, manifest, state, nodes, if (is_action_request(event)) { // for action requests, first call handler in +page.server.js // (this also determines status code) - action_result = await handle_action_request(event, leaf_node.server, await options.tracer); + action_result = await handle_action_request(event, leaf_node.server); if (action_result?.type === 'redirect') { return redirect_response(action_result.status, action_result.location); } @@ -166,8 +166,7 @@ export async function render_page(event, page, options, manifest, state, nodes, if (parent) Object.assign(data, parent.data); } return data; - }, - tracer: await options.tracer + } }); } catch (e) { load_error = /** @type {Error} */ (e); @@ -195,8 +194,7 @@ export async function render_page(event, page, options, manifest, state, nodes, resolve_opts, server_data_promise: server_promises[i], state, - csr, - tracer: await options.tracer + csr }); } catch (e) { load_error = /** @type {Error} */ (e); diff --git a/packages/kit/src/runtime/server/page/load_data.js b/packages/kit/src/runtime/server/page/load_data.js index 45ec2209b7cd..056a7e54f48a 100644 --- a/packages/kit/src/runtime/server/page/load_data.js +++ b/packages/kit/src/runtime/server/page/load_data.js @@ -13,11 +13,10 @@ import { get_node_type } from '../utils.js'; * state: import('types').SSRState; * node: import('types').SSRNode | undefined; * parent: () => Promise>; - * tracer: import('@opentelemetry/api').Tracer; * }} opts * @returns {Promise} */ -export async function load_server_data({ event, state, node, parent, tracer }) { +export async function load_server_data({ event, state, node, parent }) { if (!node?.server) return null; let is_tracking = true; @@ -73,7 +72,6 @@ export async function load_server_data({ event, state, node, parent, tracer }) { const result = await record_span({ name: 'sveltekit.load', - tracer, attributes: { 'sveltekit.load.node_id': node.server_id || 'unknown', 'sveltekit.load.node_type': get_node_type(node.server_id), @@ -201,7 +199,6 @@ export async function load_server_data({ event, state, node, parent, tracer }) { * server_data_promise: Promise; * state: import('types').SSRState; * csr: boolean; - * tracer: import('@opentelemetry/api').Tracer; * }} opts * @returns {Promise> | null>} */ @@ -213,8 +210,7 @@ export async function load_data({ server_data_promise, state, resolve_opts, - csr, - tracer + csr }) { const server_data_node = await server_data_promise; @@ -226,7 +222,6 @@ export async function load_data({ const result = await record_span({ name: 'sveltekit.load', - tracer, attributes: { 'sveltekit.load.node_id': node.universal_id || 'unknown', 'sveltekit.load.node_type': get_node_type(node.universal_id), diff --git a/packages/kit/src/runtime/server/page/respond_with_error.js b/packages/kit/src/runtime/server/page/respond_with_error.js index 670870a35291..bb3e99054507 100644 --- a/packages/kit/src/runtime/server/page/respond_with_error.js +++ b/packages/kit/src/runtime/server/page/respond_with_error.js @@ -46,13 +46,11 @@ export async function respond_with_error({ if (ssr) { state.error = true; - const tracer = await options.tracer; const server_data_promise = load_server_data({ event, state, node: default_layout, - tracer, // eslint-disable-next-line @typescript-eslint/require-await parent: async () => ({}) }); @@ -68,8 +66,7 @@ export async function respond_with_error({ resolve_opts, server_data_promise, state, - csr, - tracer + csr }); branch.push( diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index 38e71af812bf..1b5543270590 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -363,11 +363,8 @@ export async function respond(request, options, manifest, state) { disable_search(url); } - const tracer = await options.tracer; - const response = await record_span({ name: 'sveltekit.handle.root', - tracer, attributes: { 'http.route': event.route.id || 'unknown', 'http.method': event.request.method, @@ -383,7 +380,6 @@ export async function respond(request, options, manifest, state) { resolve: (event, opts) => { return record_span({ name: 'sveltekit.resolve.root', - tracer, attributes: { 'http.route': event.route.id || 'unknown' }, diff --git a/packages/kit/src/runtime/telemetry/get_tracer.js b/packages/kit/src/runtime/telemetry/get_tracer.js deleted file mode 100644 index d4198b9330ea..000000000000 --- a/packages/kit/src/runtime/telemetry/get_tracer.js +++ /dev/null @@ -1,38 +0,0 @@ -/** @import { Tracer } from '@opentelemetry/api' */ -import { DEV } from 'esm-env'; -import { noop_tracer } from './noop.js'; -import { load_otel } from './load_otel.js'; - -// this is controlled via a global flag because we need to access it in locations where we don't have access to the config -// (specifically, in `sequence`-d handle functions) -// since this is a global flag with a static value, it's safe to set it during server initialization -let is_enabled = false; - -export function enable_tracing() { - is_enabled = true; -} - -export function disable_tracing() { - is_enabled = false; -} - -/** - * @returns {Promise} The tracer instance - */ -export async function get_tracer() { - if (!is_enabled) { - return noop_tracer; - } - - const otel = await load_otel(); - if (otel === null) { - if (DEV) { - console.warn( - 'Tracing is enabled, but `@opentelemetry/api` is not available. Have you installed it?' - ); - } - return noop_tracer; - } - - return otel.tracer; -} diff --git a/packages/kit/src/runtime/telemetry/get_tracer.spec.js b/packages/kit/src/runtime/telemetry/get_tracer.spec.js deleted file mode 100644 index 1452527f47f8..000000000000 --- a/packages/kit/src/runtime/telemetry/get_tracer.spec.js +++ /dev/null @@ -1,34 +0,0 @@ -import { describe, test, expect, beforeEach, vi } from 'vitest'; -import { disable_tracing, enable_tracing, get_tracer } from './get_tracer.js'; -import { noop_tracer } from './noop.js'; -import * as load_otel from './load_otel.js'; - -describe('get_tracer', () => { - beforeEach(() => { - vi.resetAllMocks(); - disable_tracing(); - }); - - test('returns noop tracer if tracing is disabled', async () => { - const tracer = await get_tracer(); - expect(tracer).toBe(noop_tracer); - }); - - test('returns noop tracer if @opentelemetry/api is not installed, warning', async () => { - enable_tracing(); - vi.spyOn(load_otel, 'load_otel').mockResolvedValue(null); - const console_warn_spy = vi.spyOn(console, 'warn'); - - const tracer = await get_tracer(); - expect(tracer).toBe(noop_tracer); - expect(console_warn_spy).toHaveBeenCalledWith( - 'Tracing is enabled, but `@opentelemetry/api` is not available. Have you installed it?' - ); - }); - - test('returns otel tracer if @opentelemetry/api is installed', async () => { - enable_tracing(); - const tracer = await get_tracer(); - expect(tracer).not.toBe(noop_tracer); - }); -}); diff --git a/packages/kit/src/runtime/telemetry/load_otel.js b/packages/kit/src/runtime/telemetry/load_otel.js deleted file mode 100644 index 4e37b357857f..000000000000 --- a/packages/kit/src/runtime/telemetry/load_otel.js +++ /dev/null @@ -1,18 +0,0 @@ -/** @import { Tracer, SpanStatusCode } from '@opentelemetry/api' */ - -/** @type {Promise<{ tracer: Tracer, SpanStatusCode: typeof SpanStatusCode } | null> | null} */ -let otel_result = null; - -export function load_otel() { - if (otel_result) return otel_result; - otel_result = import('@opentelemetry/api') - .then((module) => { - const { trace, SpanStatusCode } = module; - return { - tracer: trace.getTracer('sveltekit'), - SpanStatusCode - }; - }) - .catch(() => null); - return otel_result; -} diff --git a/packages/kit/src/runtime/telemetry/otel.disabled.spec.js b/packages/kit/src/runtime/telemetry/otel.disabled.spec.js new file mode 100644 index 000000000000..d14fddd2d097 --- /dev/null +++ b/packages/kit/src/runtime/telemetry/otel.disabled.spec.js @@ -0,0 +1,10 @@ +import { test, expect, vi } from 'vitest'; +import { otel } from './otel.js'; + +vi.hoisted(() => { + vi.stubGlobal('__SVELTEKIT_SERVER_TRACING_ENABLED__', false); +}); + +test('otel should be null when tracing is disabled', () => { + expect(otel).toBeNull(); +}); diff --git a/packages/kit/src/runtime/telemetry/otel.enabled.spec.js b/packages/kit/src/runtime/telemetry/otel.enabled.spec.js new file mode 100644 index 000000000000..1df7b45dceb6 --- /dev/null +++ b/packages/kit/src/runtime/telemetry/otel.enabled.spec.js @@ -0,0 +1,10 @@ +import { test, expect, vi } from 'vitest'; +import { otel } from './otel.js'; + +vi.hoisted(() => { + vi.stubGlobal('__SVELTEKIT_SERVER_TRACING_ENABLED__', true); +}); + +test('otel should be defined when tracing is enabled', () => { + expect(otel).not.toBeNull(); +}); diff --git a/packages/kit/src/runtime/telemetry/otel.js b/packages/kit/src/runtime/telemetry/otel.js new file mode 100644 index 000000000000..6278d82fe645 --- /dev/null +++ b/packages/kit/src/runtime/telemetry/otel.js @@ -0,0 +1,18 @@ +/** @import { Tracer, SpanStatusCode } from '@opentelemetry/api' */ + +/** @type {{ tracer: Tracer, SpanStatusCode: typeof SpanStatusCode } | null} */ +export let otel = null; + +if (__SVELTEKIT_SERVER_TRACING_ENABLED__) { + try { + const module = await import('@opentelemetry/api'); + otel = { + tracer: module.trace.getTracer('sveltekit'), + SpanStatusCode: module.SpanStatusCode + }; + } catch { + throw new Error( + 'Tracing is enabled (see `config.kit.experimental.tracing.server` in your svelte.config.js), but `@opentelemetry/api` is not available. Have you installed it?' + ); + } +} diff --git a/packages/kit/src/runtime/telemetry/otel.missing.spec.js b/packages/kit/src/runtime/telemetry/otel.missing.spec.js new file mode 100644 index 000000000000..a02a99293cf1 --- /dev/null +++ b/packages/kit/src/runtime/telemetry/otel.missing.spec.js @@ -0,0 +1,15 @@ +import { test, expect, vi } from 'vitest'; + +vi.hoisted(() => { + vi.stubGlobal('__SVELTEKIT_SERVER_TRACING_ENABLED__', true); +}); + +vi.mock('@opentelemetry/api', () => { + throw new Error('Not available'); +}); + +test('otel should throw an error when tracing is enabled but @opentelemetry/api is not available', async () => { + await expect(import('./otel.js')).rejects.toThrow( + 'Tracing is enabled (see `config.kit.experimental.tracing.server` in your svelte.config.js), but `@opentelemetry/api` is not available. Have you installed it?' + ); +}); diff --git a/packages/kit/src/runtime/telemetry/record_span.disabled.spec.js b/packages/kit/src/runtime/telemetry/record_span.disabled.spec.js new file mode 100644 index 000000000000..7a750391d2b9 --- /dev/null +++ b/packages/kit/src/runtime/telemetry/record_span.disabled.spec.js @@ -0,0 +1,15 @@ +import { test, expect, vi } from 'vitest'; +import { record_span } from './record_span.js'; +import { noop_span } from './noop.js'; + +vi.hoisted(() => { + vi.stubGlobal('__SVELTEKIT_SERVER_TRACING_ENABLED__', false); +}); + +test('it runs function with noop span if @opentelemetry/api is not available', async () => { + const fn = vi.fn().mockResolvedValue('result'); + + const result = await record_span({ name: 'test', attributes: {}, fn }); + expect(result).toBe('result'); + expect(fn).toHaveBeenCalledWith(noop_span); +}); diff --git a/packages/kit/src/runtime/telemetry/record_span.spec.js b/packages/kit/src/runtime/telemetry/record_span.enabled.spec.js similarity index 64% rename from packages/kit/src/runtime/telemetry/record_span.spec.js rename to packages/kit/src/runtime/telemetry/record_span.enabled.spec.js index 9be6bd2c407d..ce10a866d79c 100644 --- a/packages/kit/src/runtime/telemetry/record_span.spec.js +++ b/packages/kit/src/runtime/telemetry/record_span.enabled.spec.js @@ -1,11 +1,14 @@ -import { describe, test, expect, vi } from 'vitest'; +/** @import { Span, Tracer } from '@opentelemetry/api' */ +import { describe, test, expect, vi, beforeEach } from 'vitest'; import { record_span } from './record_span.js'; -import { noop_span, noop_tracer } from './noop.js'; -import * as load_otel from './load_otel.js'; import { HttpError, Redirect } from '@sveltejs/kit/internal'; -const create_mock_span = () => - /** @type {import('@opentelemetry/api').Span} */ ( +vi.hoisted(() => { + vi.stubGlobal('__SVELTEKIT_SERVER_TRACING_ENABLED__', true); +}); + +const { tracer, span } = vi.hoisted(() => { + const mock_span = /** @type {Span} */ ( /** @type {unknown} */ ({ end: vi.fn(), setAttributes: vi.fn(), @@ -14,49 +17,42 @@ const create_mock_span = () => }) ); -/** @type {() => { tracer: import('@opentelemetry/api').Tracer, span: import('@opentelemetry/api').Span } } */ -const create_mock_tracer = () => { - const span = create_mock_span(); - const tracer = { - startActiveSpan: vi.fn().mockImplementation((_name, _options, fn) => { + const mock_tracer = /** @type {Tracer} */ ({ + startActiveSpan: vi.fn((_name, _options, fn) => { return fn(span); }), - startSpan: vi.fn().mockImplementation((_name, _options, fn) => { + startSpan: vi.fn((_name, _options, fn) => { return fn(span); }) - }; - return { tracer, span }; -}; + }); -describe('record_span', () => { - test('runs function with noop span if @opentelemetry/api is not available', async () => { - const spy = vi.spyOn(load_otel, 'load_otel').mockResolvedValue(null); - const fn = vi.fn().mockResolvedValue('result'); + return { tracer: mock_tracer, span: mock_span }; +}); - const result = await record_span({ name: 'test', tracer: noop_tracer, attributes: {}, fn }); - expect(result).toBe('result'); - expect(fn).toHaveBeenCalledWith(noop_span); - spy.mockRestore(); - }); +vi.mock(import('./otel.js'), async (original) => { + const { otel } = await original(); - test('runs function with span if @opentelemetry/api is available', async () => { - const fn = vi.fn().mockResolvedValue('result'); - const result = await record_span({ - name: 'test', - tracer: create_mock_tracer().tracer, - attributes: {}, - fn - }); - expect(result).toBe('result'); - expect(fn).not.toHaveBeenCalledWith(noop_span); + if (otel === null) { + throw new Error('Problem setting up tests; otel is null'); + } + + return { + otel: { + tracer, + SpanStatusCode: otel.SpanStatusCode + } + }; +}); + +describe('record_span', () => { + beforeEach(() => { + vi.resetAllMocks(); }); test('successful function returns result, attaching correct attributes', async () => { - const { tracer, span } = create_mock_tracer(); - const fn = vi.fn().mockResolvedValue('result'); + const fn = vi.fn(() => Promise.resolve('result')); const result = await record_span({ name: 'test', - tracer, attributes: { 'test-attribute': true }, fn }); @@ -70,14 +66,12 @@ describe('record_span', () => { }); test('HttpError sets correct attributes and re-throw, does set status for >=500', async () => { - const { tracer, span } = create_mock_tracer(); const error = new HttpError(500, 'Found but badly'); - const error_fn = vi.fn().mockRejectedValue(error); + const error_fn = vi.fn(() => Promise.reject(error)); await expect( record_span({ name: 'test', - tracer, attributes: {}, fn: error_fn }) @@ -100,14 +94,12 @@ describe('record_span', () => { }); test('HttpError sets correct attributes and re-throws, does not set status for <500', async () => { - const { tracer, span } = create_mock_tracer(); const error = new HttpError(404, 'Not found'); - const error_fn = vi.fn().mockRejectedValue(error); + const error_fn = vi.fn(() => Promise.reject(error)); await expect( record_span({ name: 'test', - tracer, attributes: {}, fn: error_fn }) @@ -122,14 +114,12 @@ describe('record_span', () => { }); test('Redirect sets correct attributes and re-throws', async () => { - const { tracer, span } = create_mock_tracer(); const error = new Redirect(302, '/redirect-location'); - const error_fn = vi.fn().mockRejectedValue(error); + const error_fn = vi.fn(() => Promise.reject(error)); await expect( record_span({ name: 'test', - tracer, attributes: {}, fn: error_fn }) @@ -145,14 +135,12 @@ describe('record_span', () => { }); test('Generic Error sets correct attributes and re-throws', async () => { - const { tracer, span } = create_mock_tracer(); const error = new Error('Something went wrong'); - const error_fn = vi.fn().mockRejectedValue(error); + const error_fn = vi.fn(() => Promise.reject(error)); await expect( record_span({ name: 'test', - tracer, attributes: {}, fn: error_fn }) @@ -174,14 +162,12 @@ describe('record_span', () => { }); test('Non-Error object sets correct attributes and re-throws', async () => { - const { tracer, span } = create_mock_tracer(); const error = 'string error'; - const error_fn = vi.fn().mockRejectedValue(error); + const error_fn = vi.fn(() => Promise.reject(error)); await expect( record_span({ name: 'test', - tracer, attributes: {}, fn: error_fn }) diff --git a/packages/kit/src/runtime/telemetry/record_span.js b/packages/kit/src/runtime/telemetry/record_span.js index 2401643a4a7f..0f6b7aa3eb66 100644 --- a/packages/kit/src/runtime/telemetry/record_span.js +++ b/packages/kit/src/runtime/telemetry/record_span.js @@ -1,30 +1,26 @@ -/** @import { Attributes, Span, Tracer } from '@opentelemetry/api' */ +/** @import { Attributes, Span } from '@opentelemetry/api' */ import { HttpError, Redirect } from '@sveltejs/kit/internal'; -import { load_otel } from './load_otel.js'; import { noop_span } from './noop.js'; +import { otel } from './otel.js'; /** * @template T * @param {Object} options * @param {string} options.name - * @param {Tracer} options.tracer * @param {Attributes} options.attributes * @param {function(Span): Promise} options.fn * @returns {Promise} */ -export async function record_span({ name, tracer, attributes, fn }) { - const otel = await load_otel(); +export async function record_span({ name, attributes, fn }) { if (otel === null) { return fn(noop_span); } - const { SpanStatusCode } = otel; + const { SpanStatusCode, tracer } = otel; return tracer.startActiveSpan(name, { attributes }, async (span) => { try { - const result = await fn(span); - span.end(); - return result; + return await fn(span); } catch (error) { if (error instanceof HttpError) { span.setAttributes({ @@ -67,9 +63,10 @@ export async function record_span({ name, tracer, attributes, fn }) { }); span.setStatus({ code: SpanStatusCode.ERROR }); } - span.end(); throw error; + } finally { + span.end(); } }); } diff --git a/packages/kit/src/types/global-private.d.ts b/packages/kit/src/types/global-private.d.ts index ab659a8db5c5..4008f69c615a 100644 --- a/packages/kit/src/types/global-private.d.ts +++ b/packages/kit/src/types/global-private.d.ts @@ -4,6 +4,8 @@ declare global { const __SVELTEKIT_APP_VERSION_POLL_INTERVAL__: number; const __SVELTEKIT_DEV__: boolean; const __SVELTEKIT_EMBEDDED__: boolean; + /** True if `config.kit.experimental.tracing.server` is `true` */ + const __SVELTEKIT_SERVER_TRACING_ENABLED__: boolean; /** True if `config.kit.router.resolution === 'client'` */ const __SVELTEKIT_CLIENT_ROUTING__: boolean; /** diff --git a/packages/kit/src/types/internal.d.ts b/packages/kit/src/types/internal.d.ts index 4354fa2fe055..17e2425e3c17 100644 --- a/packages/kit/src/types/internal.d.ts +++ b/packages/kit/src/types/internal.d.ts @@ -29,7 +29,6 @@ import { RequestOptions, TrailingSlash } from './private.js'; -import { Tracer } from '@opentelemetry/api'; export interface ServerModule { Server: typeof InternalServer; @@ -436,7 +435,6 @@ export interface SSROptions { }): string; error(values: { message: string; status: number }): string; }; - tracer: Promise; version_hash: string; } From 65752bcf1557938664e070232beb47105a2736af Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Wed, 23 Jul 2025 17:48:50 -0600 Subject: [PATCH 06/74] chore: merge_tracing function --- packages/kit/kit.vitest.config.js | 2 +- packages/kit/src/exports/hooks/sequence.js | 6 +- .../kit/src/exports/hooks/sequence.spec.js | 2 +- packages/kit/src/exports/public.d.ts | 18 ++++-- packages/kit/src/runtime/client/client.js | 2 +- .../kit/src/runtime/server/page/actions.js | 14 ++--- .../kit/src/runtime/server/page/load_data.js | 14 ++--- packages/kit/src/runtime/server/respond.js | 55 +++++++++---------- packages/kit/src/runtime/utils.js | 18 ++++++ packages/kit/types/index.d.ts | 18 ++++-- 10 files changed, 85 insertions(+), 64 deletions(-) diff --git a/packages/kit/kit.vitest.config.js b/packages/kit/kit.vitest.config.js index f443a76ae109..c6fe0d9a5d23 100644 --- a/packages/kit/kit.vitest.config.js +++ b/packages/kit/kit.vitest.config.js @@ -16,7 +16,7 @@ export default defineConfig({ '__sveltekit/paths': fileURLToPath(new URL('./test/mocks/path.js', import.meta.url)) }, // shave a couple seconds off the tests - isolate: false, + isolate: true, poolOptions: { threads: { singleThread: true diff --git a/packages/kit/src/exports/hooks/sequence.js b/packages/kit/src/exports/hooks/sequence.js index 4cb55bb890a6..e0ed501b3944 100644 --- a/packages/kit/src/exports/hooks/sequence.js +++ b/packages/kit/src/exports/hooks/sequence.js @@ -1,6 +1,7 @@ /** @import { Handle, RequestEvent, ResolveOptions } from '@sveltejs/kit' */ /** @import { MaybePromise } from 'types' */ import { with_event } from '../../runtime/app/server/event.js'; +import { merge_tracing } from '../../runtime/utils.js'; import { record_span } from '../../runtime/telemetry/record_span.js'; /** @@ -82,7 +83,6 @@ export function sequence(...handlers) { // there's an assumption here that people aren't doing something insane like sequence(() => {}, sequence(() => {})) // worst case there is that future spans get a lower-down span as their root span -- the tracing would still work, // it'd just look a little weird - const { rootSpan } = event.tracing; return apply_handle(0, event, {}); /** @@ -99,8 +99,8 @@ export function sequence(...handlers) { attributes: { 'sveltekit.handle.child.index': i }, - fn: async (span) => { - const traced_event = { ...event, tracing: { rootSpan, currentSpan: span } }; + fn: async (current) => { + const traced_event = merge_tracing(event, current); return await with_event(traced_event, () => handle({ event: traced_event, diff --git a/packages/kit/src/exports/hooks/sequence.spec.js b/packages/kit/src/exports/hooks/sequence.spec.js index 79a9eee95aa7..fe16d5a0bdfb 100644 --- a/packages/kit/src/exports/hooks/sequence.spec.js +++ b/packages/kit/src/exports/hooks/sequence.spec.js @@ -5,7 +5,7 @@ import { installPolyfills } from '../node/polyfills.js'; installPolyfills(); const dummy_event = /** @type {import('@sveltejs/kit').RequestEvent} */ ({ - tracing: { rootSpan: {} } + tracing: { root: {} } }); test('applies handlers in sequence', async () => { diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 8f1d76408689..527190725760 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -985,10 +985,12 @@ export interface LoadEvent< * @since 2.26.0 // TODO: update this before publishing */ tracing: { + /** Whether tracing is enabled. */ + enabled: boolean; /** The root span for the request. This span is named `sveltekit.handle.root`. */ - rootSpan: Span; + root: Span; /** The span associated with the current `load` function. */ - currentSpan: Span; + current: Span; }; } @@ -1271,10 +1273,12 @@ export interface RequestEvent< * @since 2.26.0 // TODO: update this before publishing */ tracing: { + /** Whether tracing is enabled. */ + enabled: boolean; /** The root span for the request. This span is named `sveltekit.handle.root`. */ - rootSpan: Span; + root: Span; /** The span associated with the current `handle` hook, `load` function, or form action. */ - currentSpan: Span; + current: Span; }; } @@ -1438,10 +1442,12 @@ export interface ServerLoadEvent< * @since 2.26.0 // TODO: update this before publishing */ tracing: { + /** Whether tracing is enabled. */ + enabled: boolean; /** The root span for the request. This span is named `sveltekit.handle.root`. */ - rootSpan: Span; + root: Span; /** The span associated with the current server `load` function. */ - currentSpan: Span; + current: Span; }; } diff --git a/packages/kit/src/runtime/client/client.js b/packages/kit/src/runtime/client/client.js index d70003bf9c25..f463c01fb160 100644 --- a/packages/kit/src/runtime/client/client.js +++ b/packages/kit/src/runtime/client/client.js @@ -676,7 +676,7 @@ async function load_node({ loader, parent, url, params, route, server_data_node /** @type {import('@sveltejs/kit').LoadEvent} */ const load_input = { - tracing: { rootSpan: noop_span, currentSpan: noop_span }, + tracing: { enabled: false, root: noop_span, current: noop_span }, route: new Proxy(route, { get: (target, key) => { if (is_tracking) { diff --git a/packages/kit/src/runtime/server/page/actions.js b/packages/kit/src/runtime/server/page/actions.js index 4bdf3e932235..31b6a194cb54 100644 --- a/packages/kit/src/runtime/server/page/actions.js +++ b/packages/kit/src/runtime/server/page/actions.js @@ -9,6 +9,7 @@ import { is_form_content_type, negotiate } from '../../../utils/http.js'; import { handle_error_and_jsonify } from '../utils.js'; import { with_event } from '../../app/server/event.js'; import { record_span } from '../../telemetry/record_span.js'; +import { merge_tracing } from '../../utils.js'; /** @param {RequestEvent} event */ export function is_action_json_request(event) { @@ -256,17 +257,10 @@ async function call_action(event, actions) { 'sveltekit.action.name': name, 'http.route': event.route.id || 'unknown' }, - fn: async (action_span) => { - const traced_event = { - ...event, - tracing: { - rootSpan: event.tracing.rootSpan, - currentSpan: action_span - } - }; - const result = await with_event(traced_event, () => action(traced_event)); + fn: async (current) => { + const result = await with_event(merge_tracing(event, current), () => action(event)); if (result instanceof ActionFailure) { - action_span.setAttributes({ + current.setAttributes({ 'sveltekit.action.result.type': 'failure', 'sveltekit.action.result.status': result.status }); diff --git a/packages/kit/src/runtime/server/page/load_data.js b/packages/kit/src/runtime/server/page/load_data.js index 056a7e54f48a..6814e0ed9bd3 100644 --- a/packages/kit/src/runtime/server/page/load_data.js +++ b/packages/kit/src/runtime/server/page/load_data.js @@ -1,7 +1,7 @@ import { DEV } from 'esm-env'; import { disable_search, make_trackable } from '../../../utils/url.js'; import { validate_depends, validate_load_response } from '../../shared.js'; -import { b64_encode } from '../../utils.js'; +import { b64_encode, merge_tracing } from '../../utils.js'; import { with_event } from '../../app/server/event.js'; import { record_span } from '../../telemetry/record_span.js'; import { get_node_type } from '../utils.js'; @@ -78,9 +78,8 @@ export async function load_server_data({ event, state, node, parent }) { 'sveltekit.load.environment': 'server', 'http.route': event.route.id || 'unknown' }, - fn: async (span) => { - const rootSpan = event.tracing.rootSpan; - const traced_event = { ...event, tracing: { rootSpan, currentSpan: span } }; + fn: async (current) => { + const traced_event = merge_tracing(event, current); const result = await with_event(traced_event, () => load.call(null, { ...traced_event, @@ -228,11 +227,10 @@ export async function load_data({ 'sveltekit.load.environment': 'server', 'http.route': event.route.id || 'unknown' }, - fn: async (span) => { - const rootSpan = event.tracing.rootSpan; - const tracing = { rootSpan, currentSpan: span }; + fn: async (current) => { + const traced_event = merge_tracing(event, current); const result = await load.call(null, { - tracing, + ...traced_event, url: event.url, params: event.params, data: server_data_node?.data ?? null, diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index 1b5543270590..4391d344fbb6 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -35,6 +35,7 @@ import { } from '../pathname.js'; import { with_event } from '../app/server/event.js'; import { record_span } from '../telemetry/record_span.js'; +import { merge_tracing } from '../utils.js'; /* global __SVELTEKIT_ADAPTER_NAME__ */ /* global __SVELTEKIT_DEV__ */ @@ -372,8 +373,8 @@ export async function respond(request, options, manifest, state) { 'sveltekit.is_data_request': is_data_request, 'sveltekit.is_sub_request': event.isSubRequest }, - fn: async (rootSpan) => { - const traced_event = { ...event, tracing: { rootSpan, currentSpan: rootSpan } }; + fn: async (root_span) => { + const traced_event = merge_tracing(event, root_span); return await with_event(traced_event, () => options.hooks.handle({ event: traced_event, @@ -383,36 +384,34 @@ export async function respond(request, options, manifest, state) { attributes: { 'http.route': event.route.id || 'unknown' }, - fn: async (resolveSpan) => { + fn: async (resolve_span) => { // counter-intuitively, we need to clear the event, so that it's not // e.g. accessible when loading modules needed to handle the request return with_event(null, () => - resolve( - { ...event, tracing: { rootSpan, currentSpan: resolveSpan } }, - page_nodes, - opts - ).then((response) => { - // add headers/cookies here, rather than inside `resolve`, so that we - // can do it once for all responses instead of once per `return` - for (const key in headers) { - const value = headers[key]; - response.headers.set(key, /** @type {string} */ (value)); + resolve(merge_tracing(event, resolve_span), page_nodes, opts).then( + (response) => { + // add headers/cookies here, rather than inside `resolve`, so that we + // can do it once for all responses instead of once per `return` + for (const key in headers) { + const value = headers[key]; + response.headers.set(key, /** @type {string} */ (value)); + } + + add_cookies_to_headers(response.headers, Object.values(new_cookies)); + + if (state.prerendering && event.route.id !== null) { + response.headers.set('x-sveltekit-routeid', encodeURI(event.route.id)); + } + + resolve_span.setAttributes({ + 'http.response.status_code': response.status, + 'http.response.body.size': + response.headers.get('content-length') || 'unknown' + }); + + return response; } - - add_cookies_to_headers(response.headers, Object.values(new_cookies)); - - if (state.prerendering && event.route.id !== null) { - response.headers.set('x-sveltekit-routeid', encodeURI(event.route.id)); - } - - resolveSpan.setAttributes({ - 'http.response.status_code': response.status, - 'http.response.body.size': - response.headers.get('content-length') || 'unknown' - }); - - return response; - }) + ) ); } }); diff --git a/packages/kit/src/runtime/utils.js b/packages/kit/src/runtime/utils.js index 2da4498d9b7f..9b1aa19387ad 100644 --- a/packages/kit/src/runtime/utils.js +++ b/packages/kit/src/runtime/utils.js @@ -1,3 +1,5 @@ +/** @import { Span } from '@opentelemetry/api'; */ + /** * @param {string} text * @returns {ArrayBufferLike} @@ -53,3 +55,19 @@ export function get_relative_path(from, to) { return from_parts.concat(to_parts).join('/'); } + +/** + * @template {{ tracing: { enabled: boolean, root: Span, current: Span } }} T + * @param {T} event_like + * @param {Span} current + * @returns {T} + */ +export function merge_tracing(event_like, current) { + return { + ...event_like, + tracing: { + ...event_like.tracing, + current + } + }; +} diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 2a7ea0168da6..e6d675fea51f 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -967,10 +967,12 @@ declare module '@sveltejs/kit' { * @since 2.26.0 // TODO: update this before publishing */ tracing: { + /** Whether tracing is enabled. */ + enabled: boolean; /** The root span for the request. This span is named `sveltekit.handle.root`. */ - rootSpan: Span; + root: Span; /** The span associated with the current `load` function. */ - currentSpan: Span; + current: Span; }; } @@ -1253,10 +1255,12 @@ declare module '@sveltejs/kit' { * @since 2.26.0 // TODO: update this before publishing */ tracing: { + /** Whether tracing is enabled. */ + enabled: boolean; /** The root span for the request. This span is named `sveltekit.handle.root`. */ - rootSpan: Span; + root: Span; /** The span associated with the current `handle` hook, `load` function, or form action. */ - currentSpan: Span; + current: Span; }; } @@ -1420,10 +1424,12 @@ declare module '@sveltejs/kit' { * @since 2.26.0 // TODO: update this before publishing */ tracing: { + /** Whether tracing is enabled. */ + enabled: boolean; /** The root span for the request. This span is named `sveltekit.handle.root`. */ - rootSpan: Span; + root: Span; /** The span associated with the current server `load` function. */ - currentSpan: Span; + current: Span; }; } From e50615b33e37f9401d2fbba1e03f51abdc42eba2 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Wed, 23 Jul 2025 17:49:27 -0600 Subject: [PATCH 07/74] fix rich's bad comment that shouldn't have ever existed >:( --- packages/kit/kit.vitest.config.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/kit/kit.vitest.config.js b/packages/kit/kit.vitest.config.js index c6fe0d9a5d23..55e822235729 100644 --- a/packages/kit/kit.vitest.config.js +++ b/packages/kit/kit.vitest.config.js @@ -15,7 +15,6 @@ export default defineConfig({ alias: { '__sveltekit/paths': fileURLToPath(new URL('./test/mocks/path.js', import.meta.url)) }, - // shave a couple seconds off the tests isolate: true, poolOptions: { threads: { From 5b583ec27ca14b94c62fc7c50dac11d5ef304a7a Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Wed, 23 Jul 2025 17:55:28 -0600 Subject: [PATCH 08/74] test stuff --- packages/kit/src/runtime/server/respond.js | 2 +- .../kit/test/apps/basics/test/server.test.js | 69 ++++++++++--------- 2 files changed, 37 insertions(+), 34 deletions(-) diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index 4391d344fbb6..f5f17a75d6b8 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -380,7 +380,7 @@ export async function respond(request, options, manifest, state) { event: traced_event, resolve: (event, opts) => { return record_span({ - name: 'sveltekit.resolve.root', + name: 'sveltekit.resolve', attributes: { 'http.route': event.route.id || 'unknown' }, diff --git a/packages/kit/test/apps/basics/test/server.test.js b/packages/kit/test/apps/basics/test/server.test.js index 148a2a821b74..5d6c23c8a1be 100644 --- a/packages/kit/test/apps/basics/test/server.test.js +++ b/packages/kit/test/apps/basics/test/server.test.js @@ -1,3 +1,4 @@ +/** @import { ReadableSpan } from '@opentelemetry/sdk-trace-node' */ import process from 'node:process'; import { expect } from '@playwright/test'; import { test } from '../../../utils.js'; @@ -771,14 +772,16 @@ test.describe('$app/environment', () => { test.describe('tracing', () => { // Helper function to find the resolve.root span deep in the handle.child chain - /** @param {import('@opentelemetry/sdk-trace-node').ReadableSpan} span */ - /** @returns {import('@opentelemetry/sdk-trace-node').ReadableSpan | null} */ - function findResolveRootSpan(span) { - if (span.name === 'sveltekit.resolve.root') { + /** + * @param {ReadableSpan} span + * @returns {ReadableSpan | null} + */ + function find_resolve_root_span(span) { + if (span.name === 'sveltekit.resolve') { return span; } for (const child of span.children || []) { - const found = findResolveRootSpan(child); + const found = find_resolve_root_span(child); if (found) return found; } return null; @@ -826,10 +829,10 @@ test.describe('tracing', () => { }); // Find and verify the resolve.root span - const resolveRootSpan = findResolveRootSpan(trace); - expect(resolveRootSpan).not.toBeNull(); - expect(resolveRootSpan).toEqual({ - name: 'sveltekit.resolve.root', + const resolve_root_span = find_resolve_root_span(trace); + expect(resolve_root_span).not.toBeNull(); + expect(resolve_root_span).toEqual({ + name: 'sveltekit.resolve', status: { code: 0 }, start_time: [expect.any(Number), expect.any(Number)], end_time: [expect.any(Number), expect.any(Number)], @@ -918,10 +921,10 @@ test.describe('tracing', () => { }); // Find and verify the resolve.root span - const resolveRootSpan = findResolveRootSpan(trace); - expect(resolveRootSpan).not.toBeNull(); - expect(resolveRootSpan).toEqual({ - name: 'sveltekit.resolve.root', + const resolve_root_span = find_resolve_root_span(trace); + expect(resolve_root_span).not.toBeNull(); + expect(resolve_root_span).toEqual({ + name: 'sveltekit.resolve', status: { code: 0 }, start_time: [expect.any(Number), expect.any(Number)], end_time: [expect.any(Number), expect.any(Number)], @@ -959,11 +962,11 @@ test.describe('tracing', () => { const redirect_trace_id = traces[0].trace_id; const destination_trace_id = traces[1].trace_id; - const redirectTrace = traces[0]; - const destinationTrace = traces[1]; + const redirect_trace = traces[0]; + const destination_trace = traces[1]; // Verify redirect trace root span structure - expect(redirectTrace).toEqual({ + expect(redirect_trace).toEqual({ name: 'sveltekit.handle.root', status: { code: 0 }, start_time: [expect.any(Number), expect.any(Number)], @@ -990,10 +993,10 @@ test.describe('tracing', () => { }); // Find and verify the redirect resolve.root span - const redirectResolveRootSpan = findResolveRootSpan(redirectTrace); - expect(redirectResolveRootSpan).not.toBeNull(); - expect(redirectResolveRootSpan).toEqual({ - name: 'sveltekit.resolve.root', + const redirect_resolve_root_span = find_resolve_root_span(redirect_trace); + expect(redirect_resolve_root_span).not.toBeNull(); + expect(redirect_resolve_root_span).toEqual({ + name: 'sveltekit.resolve', status: { code: 0 }, start_time: [expect.any(Number), expect.any(Number)], end_time: [expect.any(Number), expect.any(Number)], @@ -1021,7 +1024,7 @@ test.describe('tracing', () => { }); // Verify destination trace root span structure - expect(destinationTrace).toEqual({ + expect(destination_trace).toEqual({ name: 'sveltekit.handle.root', status: { code: 0 }, start_time: [expect.any(Number), expect.any(Number)], @@ -1048,10 +1051,10 @@ test.describe('tracing', () => { }); // Find and verify the destination resolve.root span - const destinationResolveRootSpan = findResolveRootSpan(destinationTrace); - expect(destinationResolveRootSpan).not.toBeNull(); - expect(destinationResolveRootSpan).toEqual({ - name: 'sveltekit.resolve.root', + const destination_resolve_root_span = find_resolve_root_span(destination_trace); + expect(destination_resolve_root_span).not.toBeNull(); + expect(destination_resolve_root_span).toEqual({ + name: 'sveltekit.resolve', status: { code: 0 }, start_time: [expect.any(Number), expect.any(Number)], end_time: [expect.any(Number), expect.any(Number)], @@ -1140,10 +1143,10 @@ test.describe('tracing', () => { }); // Find and verify the resolve.root span - const resolveRootSpan = findResolveRootSpan(trace); - expect(resolveRootSpan).not.toBeNull(); - expect(resolveRootSpan).toEqual({ - name: 'sveltekit.resolve.root', + const resolve_root_span = find_resolve_root_span(trace); + expect(resolve_root_span).not.toBeNull(); + expect(resolve_root_span).toEqual({ + name: 'sveltekit.resolve', status: { code: 0 }, start_time: [expect.any(Number), expect.any(Number)], end_time: [expect.any(Number), expect.any(Number)], @@ -1206,10 +1209,10 @@ test.describe('tracing', () => { }); // Find and verify the resolve.root span - const resolveRootSpan = findResolveRootSpan(trace); - expect(resolveRootSpan).not.toBeNull(); - expect(resolveRootSpan).toEqual({ - name: 'sveltekit.resolve.root', + const resolve_root_span = find_resolve_root_span(trace); + expect(resolve_root_span).not.toBeNull(); + expect(resolve_root_span).toEqual({ + name: 'sveltekit.resolve', status: { code: 0 }, start_time: [expect.any(Number), expect.any(Number)], end_time: [expect.any(Number), expect.any(Number)], From 90e961d18bce5cfb2dad75725043e0fe4b61504b Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Wed, 23 Jul 2025 17:58:33 -0600 Subject: [PATCH 09/74] Update packages/kit/test/utils.js Co-authored-by: Rich Harris --- packages/kit/test/utils.js | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/packages/kit/test/utils.js b/packages/kit/test/utils.js index eba4a5fd1a03..012f32cb10cc 100644 --- a/packages/kit/test/utils.js +++ b/packages/kit/test/utils.js @@ -151,16 +151,13 @@ export const test = base.extend({ function read_traces(test_id) { const raw = fs.readFileSync('test/spans.jsonl', 'utf8').split('\n').filter(Boolean); const traces = /** @type {SpanData[]} */ (raw.map((line) => JSON.parse(line))); - const root_traces = traces.filter( - (trace) => trace.parent_span_id === undefined && trace.attributes.test_id === test_id - ); - if (root_traces.length === 0) { - return []; - } - return root_traces.map((root_trace) => { - const child_traces = traces.filter((span) => span.trace_id === root_trace.trace_id); - return build_span_tree(root_trace, child_traces); - }); + + return traces + .filter((t) => t.parent_span_id === undefined && t.attributes.test_id === test_id) + .map((root_trace) => { + const child_traces = traces.filter((span) => span.trace_id === root_trace.trace_id); + return build_span_tree(root_trace, child_traces); + }); } await use(read_traces); From dd516a93bc56c2755736f65b09381d85804f134d Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 24 Jul 2025 11:21:19 -0600 Subject: [PATCH 10/74] i am truly among the dumbest --- packages/kit/src/runtime/server/respond.js | 9 ++++++++- packages/kit/test/apps/basics/src/hooks.server.js | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index f5f17a75d6b8..0a42cf3b1211 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -374,7 +374,14 @@ export async function respond(request, options, manifest, state) { 'sveltekit.is_sub_request': event.isSubRequest }, fn: async (root_span) => { - const traced_event = merge_tracing(event, root_span); + const traced_event = { + ...event, + tracing: { + enabled: __SVELTEKIT_SERVER_TRACING_ENABLED__, + root: root_span, + current: root_span + } + }; return await with_event(traced_event, () => options.hooks.handle({ event: traced_event, diff --git a/packages/kit/test/apps/basics/src/hooks.server.js b/packages/kit/test/apps/basics/src/hooks.server.js index 4c13cf54da2b..de49781e8068 100644 --- a/packages/kit/test/apps/basics/src/hooks.server.js +++ b/packages/kit/test/apps/basics/src/hooks.server.js @@ -53,7 +53,7 @@ export const handle = sequence( ({ event, resolve }) => { const test_id = !building && event.url.searchParams.get('test_id'); if (test_id) { - event.tracing.rootSpan.setAttribute('test_id', test_id); + event.tracing.root.setAttribute('test_id', test_id); } return resolve(event); }, From 962daf7e19a97354535681da471a201f9835424d Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 24 Jul 2025 11:27:01 -0600 Subject: [PATCH 11/74] types --- packages/kit/types/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index e3acf1721503..74efa1ac2f1d 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -3,8 +3,8 @@ declare module '@sveltejs/kit' { import type { SvelteConfig } from '@sveltejs/vite-plugin-svelte'; - import type { Span } from '@opentelemetry/api'; import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams, ResolvedPathname } from '$app/types'; + import type { Span } from '@opentelemetry/api'; /** * [Adapters](https://svelte.dev/docs/kit/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. */ From 6a81d8b81d039cb941302f66b0bb4e50f80d8c95 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 24 Jul 2025 11:28:02 -0600 Subject: [PATCH 12/74] remove now-useless comment --- packages/kit/src/exports/hooks/sequence.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/kit/src/exports/hooks/sequence.js b/packages/kit/src/exports/hooks/sequence.js index e0ed501b3944..abeac6b74687 100644 --- a/packages/kit/src/exports/hooks/sequence.js +++ b/packages/kit/src/exports/hooks/sequence.js @@ -80,9 +80,6 @@ export function sequence(...handlers) { if (!length) return ({ event, resolve }) => resolve(event); return ({ event, resolve }) => { - // there's an assumption here that people aren't doing something insane like sequence(() => {}, sequence(() => {})) - // worst case there is that future spans get a lower-down span as their root span -- the tracing would still work, - // it'd just look a little weird return apply_handle(0, event, {}); /** From f143f5bf44997e82b7625de586f24c9c3450d3f4 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 24 Jul 2025 11:51:48 -0600 Subject: [PATCH 13/74] lockfile --- pnpm-lock.yaml | 1528 ++++++++++++++++++++++-------------------------- 1 file changed, 709 insertions(+), 819 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3ef69ae8311d..b0b0edb323f8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,13 +34,13 @@ importers: version: 1.51.1 '@sveltejs/eslint-config': specifier: ^8.2.0 - version: 8.2.0(@stylistic/eslint-plugin-js@2.1.0(eslint@9.29.0(jiti@2.4.2)))(eslint-config-prettier@9.1.0(eslint@9.29.0(jiti@2.4.2)))(eslint-plugin-n@17.16.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-svelte@3.9.3(eslint@9.29.0(jiti@2.4.2))(svelte@5.35.5)(ts-node@10.9.2(@types/node@18.19.119)(typescript@5.8.3)))(eslint@9.29.0(jiti@2.4.2))(typescript-eslint@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(typescript@5.8.3) + version: 8.2.0(@stylistic/eslint-plugin-js@2.1.0(eslint@9.29.0(jiti@2.5.1)))(eslint-config-prettier@9.1.0(eslint@9.29.0(jiti@2.5.1)))(eslint-plugin-n@17.16.1(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3))(eslint-plugin-svelte@3.9.3(eslint@9.29.0(jiti@2.5.1))(svelte@5.35.5)(ts-node@10.9.2(@types/node@18.19.119)(typescript@5.8.3)))(eslint@9.29.0(jiti@2.5.1))(typescript-eslint@8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3))(typescript@5.8.3) '@svitejs/changesets-changelog-github-compact': specifier: ^1.2.0 version: 1.2.0 eslint: specifier: ^9.29.0 - version: 9.29.0(jiti@2.4.2) + version: 9.29.0(jiti@2.5.1) prettier: specifier: ^3.6.0 version: 3.6.0 @@ -49,7 +49,7 @@ importers: version: 3.4.0(prettier@3.6.0)(svelte@5.35.5) typescript-eslint: specifier: ^8.35.0 - version: 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + version: 8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3) packages/adapter-auto: devDependencies: @@ -58,7 +58,7 @@ importers: version: link:../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) '@types/node': specifier: ^18.19.119 version: 18.19.119 @@ -67,7 +67,7 @@ importers: version: 5.6.3 vitest: specifier: 'catalog:' - version: 3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 3.2.3(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/adapter-cloudflare: dependencies: @@ -98,7 +98,7 @@ importers: version: 5.6.3 vitest: specifier: 'catalog:' - version: 3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 3.2.3(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/adapter-cloudflare/test/apps/pages: devDependencies: @@ -107,7 +107,7 @@ importers: version: link:../../../../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) server-side-dep: specifier: file:server-side-dep version: file:packages/adapter-cloudflare/test/apps/pages/server-side-dep @@ -116,7 +116,7 @@ importers: version: 5.35.5 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) wrangler: specifier: ^4.14.3 version: 4.14.4(@cloudflare/workers-types@4.20250508.0) @@ -128,7 +128,7 @@ importers: version: link:../../../../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -140,7 +140,7 @@ importers: version: 5.35.5 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) wrangler: specifier: ^4.14.3 version: 4.14.4(@cloudflare/workers-types@4.20250508.0) @@ -159,7 +159,7 @@ importers: devDependencies: '@netlify/edge-functions': specifier: ^2.15.1 - version: 2.15.1 + version: 2.16.2 '@netlify/functions': specifier: ^4.0.0 version: 4.1.4(rollup@4.40.1) @@ -177,7 +177,7 @@ importers: version: link:../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) '@types/node': specifier: ^18.19.119 version: 18.19.119 @@ -192,7 +192,7 @@ importers: version: 5.6.3 vitest: specifier: 'catalog:' - version: 3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 3.2.3(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/adapter-netlify/test/apps/basic: devDependencies: @@ -201,16 +201,16 @@ importers: version: link:../../../../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) netlify-cli: specifier: ^22.1.5 - version: 22.1.6(@types/node@18.19.119)(picomatch@4.0.2) + version: 22.3.0(@types/node@18.19.119)(picomatch@4.0.2)(rollup@4.40.1) svelte: specifier: ^5.23.1 version: 5.35.5 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/adapter-netlify/test/apps/edge: devDependencies: @@ -219,16 +219,16 @@ importers: version: link:../../../../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) netlify-cli: specifier: ^22.1.5 - version: 22.1.6(@types/node@18.19.119)(picomatch@4.0.2) + version: 22.3.0(@types/node@18.19.119)(picomatch@4.0.2)(rollup@4.40.1) svelte: specifier: ^5.23.1 version: 5.35.5 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/adapter-node: dependencies: @@ -253,7 +253,7 @@ importers: version: link:../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) '@types/node': specifier: ^18.19.119 version: 18.19.119 @@ -268,7 +268,7 @@ importers: version: 5.6.3 vitest: specifier: 'catalog:' - version: 3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 3.2.3(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/adapter-static: devDependencies: @@ -280,7 +280,7 @@ importers: version: link:../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) '@types/node': specifier: ^18.19.119 version: 18.19.119 @@ -295,7 +295,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/adapter-static/test/apps/prerendered: devDependencies: @@ -304,7 +304,7 @@ importers: version: link:../../../../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) sirv-cli: specifier: ^3.0.0 version: 3.0.0 @@ -313,7 +313,7 @@ importers: version: 5.35.5 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/adapter-static/test/apps/spa: devDependencies: @@ -325,7 +325,7 @@ importers: version: link:../../../../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) sirv-cli: specifier: ^3.0.0 version: 3.0.0 @@ -334,13 +334,13 @@ importers: version: 5.35.5 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/adapter-vercel: dependencies: '@vercel/nft': specifier: ^0.30.0 - version: 0.30.0(rollup@4.44.0) + version: 0.30.0(rollup@4.40.1) esbuild: specifier: ^0.25.4 version: 0.25.5 @@ -350,7 +350,7 @@ importers: version: link:../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) '@types/node': specifier: ^18.19.119 version: 18.19.119 @@ -359,7 +359,7 @@ importers: version: 5.6.3 vitest: specifier: 'catalog:' - version: 3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 3.2.3(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/amp: devDependencies: @@ -392,7 +392,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) '@types/estree': specifier: ^1.0.5 version: 1.0.7 @@ -410,10 +410,10 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) vitest: specifier: 'catalog:' - version: 3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 3.2.3(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit: dependencies: @@ -462,7 +462,7 @@ importers: version: 1.51.1 '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) '@types/connect': specifier: ^3.4.38 version: 3.4.38 @@ -489,10 +489,10 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) vitest: specifier: 'catalog:' - version: 3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 3.2.3(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/amp: devDependencies: @@ -504,7 +504,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -522,7 +522,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/basics: devDependencies: @@ -540,7 +540,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -558,7 +558,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/dev-only: devDependencies: @@ -567,7 +567,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -612,7 +612,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/embed: devDependencies: @@ -621,7 +621,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -636,7 +636,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/hash-based-routing: devDependencies: @@ -645,7 +645,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -660,7 +660,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/no-ssr: devDependencies: @@ -669,7 +669,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -684,7 +684,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/options: devDependencies: @@ -696,7 +696,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -711,7 +711,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/options-2: devDependencies: @@ -723,7 +723,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -738,7 +738,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/prerendered-app-error-pages: devDependencies: @@ -747,7 +747,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -762,7 +762,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/writes: devDependencies: @@ -771,7 +771,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -786,13 +786,13 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors: devDependencies: vitest: specifier: 'catalog:' - version: 3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 3.2.3(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/prerender-entry-generator-mismatch: devDependencies: @@ -804,7 +804,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -816,7 +816,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/prerenderable-incorrect-fragment: devDependencies: @@ -828,7 +828,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -840,7 +840,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/prerenderable-not-prerendered: devDependencies: @@ -852,7 +852,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -864,7 +864,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/private-dynamic-env: devDependencies: @@ -873,7 +873,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -885,7 +885,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/private-dynamic-env-dynamic-import: devDependencies: @@ -894,7 +894,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -906,7 +906,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/private-static-env: devDependencies: @@ -915,7 +915,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -930,7 +930,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/private-static-env-dynamic-import: devDependencies: @@ -939,7 +939,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -951,7 +951,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/server-only-folder: devDependencies: @@ -960,7 +960,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -972,7 +972,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/server-only-folder-dynamic-import: devDependencies: @@ -981,7 +981,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -993,7 +993,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/server-only-module: devDependencies: @@ -1002,7 +1002,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -1014,7 +1014,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/server-only-module-dynamic-import: devDependencies: @@ -1023,7 +1023,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -1035,7 +1035,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/service-worker-dynamic-public-env: devDependencies: @@ -1044,7 +1044,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -1056,7 +1056,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/service-worker-private-env: devDependencies: @@ -1065,7 +1065,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -1077,7 +1077,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/syntax-error: devDependencies: @@ -1086,7 +1086,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -1098,7 +1098,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/prerendering/basics: devDependencies: @@ -1107,7 +1107,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -1119,10 +1119,10 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) vitest: specifier: 'catalog:' - version: 3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 3.2.3(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/prerendering/options: devDependencies: @@ -1131,7 +1131,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -1143,10 +1143,10 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) vitest: specifier: 'catalog:' - version: 3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 3.2.3(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/prerendering/paths-base: devDependencies: @@ -1155,7 +1155,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -1167,10 +1167,10 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) vitest: specifier: 'catalog:' - version: 3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 3.2.3(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages/package: dependencies: @@ -1192,7 +1192,7 @@ importers: devDependencies: '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) '@types/node': specifier: ^18.19.119 version: 18.19.119 @@ -1255,7 +1255,7 @@ importers: version: link:../../packages/package '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) prettier: specifier: ^3.3.2 version: 3.3.3 @@ -1276,7 +1276,7 @@ importers: version: 5.6.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) packages: @@ -1313,6 +1313,14 @@ packages: resolution: {integrity: sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==} engines: {node: '>=6.9.0'} + '@babel/types@7.28.0': + resolution: {integrity: sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.28.1': + resolution: {integrity: sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==} + engines: {node: '>=6.9.0'} + '@bugsnag/browser@8.4.0': resolution: {integrity: sha512-5ZzGZtCwvhQbrMCAPAH9ruQGjVmSzjiE6qNNP2mD/8q0Yi45TWBtG/0MdlUYpDwx2lxVVHaGHqI3GBeD7B4Hqg==} @@ -1469,6 +1477,12 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.25.6': + resolution: {integrity: sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.25.4': resolution: {integrity: sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==} engines: {node: '>=18'} @@ -1481,6 +1495,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.25.6': + resolution: {integrity: sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.25.4': resolution: {integrity: sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==} engines: {node: '>=18'} @@ -1493,6 +1513,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.25.6': + resolution: {integrity: sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.25.4': resolution: {integrity: sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==} engines: {node: '>=18'} @@ -1505,6 +1531,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.25.6': + resolution: {integrity: sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.25.4': resolution: {integrity: sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==} engines: {node: '>=18'} @@ -1517,6 +1549,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.25.6': + resolution: {integrity: sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.25.4': resolution: {integrity: sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==} engines: {node: '>=18'} @@ -1529,6 +1567,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.25.6': + resolution: {integrity: sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.25.4': resolution: {integrity: sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==} engines: {node: '>=18'} @@ -1541,6 +1585,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.25.6': + resolution: {integrity: sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.4': resolution: {integrity: sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==} engines: {node: '>=18'} @@ -1553,6 +1603,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.25.6': + resolution: {integrity: sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.25.4': resolution: {integrity: sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==} engines: {node: '>=18'} @@ -1565,6 +1621,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.25.6': + resolution: {integrity: sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.25.4': resolution: {integrity: sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==} engines: {node: '>=18'} @@ -1577,6 +1639,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.25.6': + resolution: {integrity: sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.25.4': resolution: {integrity: sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==} engines: {node: '>=18'} @@ -1589,6 +1657,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.25.6': + resolution: {integrity: sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.25.4': resolution: {integrity: sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==} engines: {node: '>=18'} @@ -1601,6 +1675,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.25.6': + resolution: {integrity: sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.25.4': resolution: {integrity: sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==} engines: {node: '>=18'} @@ -1613,6 +1693,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.25.6': + resolution: {integrity: sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.25.4': resolution: {integrity: sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==} engines: {node: '>=18'} @@ -1625,6 +1711,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.25.6': + resolution: {integrity: sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.25.4': resolution: {integrity: sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==} engines: {node: '>=18'} @@ -1637,6 +1729,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.25.6': + resolution: {integrity: sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.25.4': resolution: {integrity: sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==} engines: {node: '>=18'} @@ -1649,6 +1747,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.25.6': + resolution: {integrity: sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.25.4': resolution: {integrity: sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==} engines: {node: '>=18'} @@ -1661,6 +1765,12 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.25.6': + resolution: {integrity: sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.25.4': resolution: {integrity: sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==} engines: {node: '>=18'} @@ -1673,6 +1783,12 @@ packages: cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.25.6': + resolution: {integrity: sha512-IjA+DcwoVpjEvyxZddDqBY+uJ2Snc6duLpjmkXm/v4xuS3H+3FkLZlDm9ZsAbF9rsfP3zeA0/ArNDORZgrxR/Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.4': resolution: {integrity: sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==} engines: {node: '>=18'} @@ -1685,6 +1801,12 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.25.6': + resolution: {integrity: sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.25.4': resolution: {integrity: sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==} engines: {node: '>=18'} @@ -1697,6 +1819,12 @@ packages: cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.25.6': + resolution: {integrity: sha512-l8ZCvXP0tbTJ3iaqdNf3pjaOSd5ex/e6/omLIQCVBLmHTlfXW3zAxQ4fnDmPLOB1x9xrcSi/xtCWFwCZRIaEwg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.4': resolution: {integrity: sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==} engines: {node: '>=18'} @@ -1709,6 +1837,18 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.25.6': + resolution: {integrity: sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.6': + resolution: {integrity: sha512-+SqBcAWoB1fYKmpWoQP4pGtx+pUUC//RNYhFdbcSA16617cchuryuhOCRpPsjCblKukAckWsV+aQ3UKT/RMPcA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.25.4': resolution: {integrity: sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==} engines: {node: '>=18'} @@ -1721,6 +1861,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.25.6': + resolution: {integrity: sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.25.4': resolution: {integrity: sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==} engines: {node: '>=18'} @@ -1733,6 +1879,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.25.6': + resolution: {integrity: sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.25.4': resolution: {integrity: sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==} engines: {node: '>=18'} @@ -1745,6 +1897,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.25.6': + resolution: {integrity: sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.25.4': resolution: {integrity: sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==} engines: {node: '>=18'} @@ -1757,6 +1915,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.25.6': + resolution: {integrity: sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.7.0': resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1803,6 +1967,9 @@ packages: resolution: {integrity: sha512-OIHZrb2ImZ7XG85HXOONLcJWGosv7sIvM2ifAPQVhg9Lv7qdmMBNVaai4QTdyuaqbKM5eO6sLSQOYI7wEQeCJQ==} engines: {node: '>=14'} + '@fastify/accept-negotiator@2.0.1': + resolution: {integrity: sha512-/c/TW2bO/v9JeEgoD/g1G5GxGeCF1Hafdf79WPmUlgYiBXummY0oX3VVq4yFkKKVBKDNlaDUYoab7g38RpPqCQ==} + '@fastify/ajv-compiler@3.6.0': resolution: {integrity: sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==} @@ -2142,21 +2309,21 @@ packages: '@netlify/binary-info@1.0.0': resolution: {integrity: sha512-4wMPu9iN3/HL97QblBsBay3E1etIciR84izI3U+4iALY+JHCrI+a2jO0qbAZ/nxKoegypYEaiiqWXylm+/zfrw==} - '@netlify/blobs@10.0.1': - resolution: {integrity: sha512-Mbf5WkJlbR5nWA8LgA9CH+dVg7yKxoRXr1jfl1CdzEsRAVIJROPCTXGUYI5N7Q6vk/py0fVLbEie+N9d7eYVdw==} + '@netlify/blobs@10.0.5': + resolution: {integrity: sha512-igbARa6gUII83lZdloe0zQzf2YLqJOZ3/3k2GMkEFFNxfLptAjvnh1z6WtFVV6bbO2IR2qOeuS2uaWRXeTNtlw==} engines: {node: ^14.16.0 || >=16.0.0} '@netlify/blobs@9.1.6': resolution: {integrity: sha512-RR3t5fv7CkGVJiylOTLf/YaHPyrcWmhHW3zX3EK/9UQsnTi8jPxP7B2nyjgRjAx5S4YTzJQP+FmbQlGKdogALQ==} engines: {node: ^14.16.0 || >=16.0.0} - '@netlify/build-info@10.0.6': - resolution: {integrity: sha512-wWMCf1IQMpYj5vp5kuZY7EvNdDbfCg77UvCKjSmHTTgWxHmb9UUOVNRH4J/YnP8HIa9i6YMfpp2ix+V34O239A==} + '@netlify/build-info@10.0.7': + resolution: {integrity: sha512-RZmSg0wekEUtPklRR8z6rsG5TPXRfT2EnamDBp94ZTUixDxDk07UCMBiz2hMKMg3qA6KTW6csuFNruvD3jw5Kw==} engines: {node: '>=18.14.0'} hasBin: true - '@netlify/build@33.4.6': - resolution: {integrity: sha512-f0KlSKBfYqvisu2UkmqaTD6fFgjpwVNvf4PdOEhX7FIMv5kM2mlk20hWKTMF7ZXu6UzBNgbAbsoCukKt8qQwSw==} + '@netlify/build@34.2.5': + resolution: {integrity: sha512-ArhIDMrixprQ1c3i+BLxghZut6Uhjt0A+/wgiwNjXrlvjQdngFB14eTiOl952wopjZ62CrxROfARcXSgwIwwEQ==} engines: {node: '>=18.14.0'} hasBin: true peerDependencies: @@ -2170,8 +2337,8 @@ packages: resolution: {integrity: sha512-NGkTvsVWs8gbd/wKOQnGjjxtaeTS+2UbqF/eZ5A/hFCXMNWf6xMQ7BcBM+pWLojHJWg/o8P1VgCZ1FDa8Zni4w==} engines: {node: '>=18.14.0'} - '@netlify/config@23.0.10': - resolution: {integrity: sha512-GTfudAUBfdNA0RwvUIrwoQrsG0GdQBpBnWfmVU/UHWYOnB3Yj+x3ETmOOSdPN8CXnqJqDd8Ey2h0iVqQ/mOcGg==} + '@netlify/config@23.2.0': + resolution: {integrity: sha512-zlI792/efPUY1XKtBML2OJBgKMyfNQIeGEYibH8SqeDxPjNuCy0qELE0U9Sc6+Ss34XryPBUPdV60tYhSoe6lw==} engines: {node: '>=18.14.0'} hasBin: true @@ -2179,23 +2346,31 @@ packages: resolution: {integrity: sha512-5QPVts2j7RHMNVPVB7E28TC564TarS2JDTfMzKGzCrAY35bvOcfJ60Hhp8DOVjI13+BJgN37srUJP4OBDIXCfg==} engines: {node: ^18.14.0 || >=20} - '@netlify/dev-utils@3.2.1': - resolution: {integrity: sha512-a96wZheD3duD20aEJXBIui73GewRIcKwsXyzyFyerrsDffQjaWFuWxU9fnVSiunl6UVrvpBjWMJRGkCv4zf2KQ==} + '@netlify/dev-utils@3.3.0': + resolution: {integrity: sha512-bW8akt30XHUY3Yh4x7pB/Yis5yCafQxbfAGAAZgHlOYfG1WqlazFsTd9OvW5d8C3g3Y2H/JA2Oy03pTBFPtSkg==} engines: {node: ^18.14.0 || >=20} - '@netlify/edge-bundler@14.0.6': - resolution: {integrity: sha512-wfIS26778TG34C3Ma4vhYVTviUuZMD1cWVW/G3m9qZ4MPqC3xII66mmJOdHSfBhwXNeu8tt/b3YoFO0b/nJO0Q==} + '@netlify/dev-utils@4.1.0': + resolution: {integrity: sha512-ftDT7G2IKCwcjULat/I5fbWwqgXhcJ1Vw7Xmda23qNLYhL9YxHn1FvIe10oHZuR/0ZHIUULuvOmswLdeoC6hqQ==} + engines: {node: ^18.14.0 || >=20} + + '@netlify/edge-bundler@14.2.2': + resolution: {integrity: sha512-APXlNsMioyd1AMECuWkkxJ6eoASYwXs8T8149IuM65KhQMR40OsPpcgt/ceg/0GydXceymHqZnkNwbapqgnvOg==} engines: {node: '>=18.14.0'} - '@netlify/edge-functions-bootstrap@2.13.0': - resolution: {integrity: sha512-8qvD/yBT3e3p5jsdFdm7VAIWXGLNnzw0n257gsmFPeKcbO/+sZMd05q/wVH2y36w/nWo+o9pRZYOJ9GqmLEgzw==} + '@netlify/edge-functions-bootstrap@2.14.0': + resolution: {integrity: sha512-Fs1cQ+XKfKr2OxrAvmX+S46CJmrysxBdCUCTk/wwcCZikrDvsYUFG7FTquUl4JfAf9taYYyW/tPv35gKOKS8BQ==} + + '@netlify/edge-functions@2.15.7': + resolution: {integrity: sha512-VVKxtocaRYBcs/+7ugvtAyTb0V5/qcBrQjWWxEPcotJC2xYat8b63M/+VTayDhbEqmKmGXj6FwSWG96xtODrbQ==} + engines: {node: '>=18.0.0'} - '@netlify/edge-functions@2.15.1': - resolution: {integrity: sha512-iu9FYYlD6crNfX8GqS5vywfkfdWWpMqnqzXrGh67iB7b+KdTPpPXsRNSRxfvL/o3GO9HJc/zmTMwXhPXDn/2fA==} + '@netlify/edge-functions@2.16.2': + resolution: {integrity: sha512-vpNT/VrfvymLx9MH46cuvTfPfEVZtpkwdM5atApzWLUrbyA0pgooAx2H0jupJk+u8yTfEYZCMvtsENEZO82agw==} engines: {node: '>=18.0.0'} - '@netlify/functions-utils@6.0.10': - resolution: {integrity: sha512-PqXyvmVmrNQgVZpyuWykS4mX7Tm2Ry8Ys/nWlDR/cHv2E+MaRiyyneAN4qrCe25z6mSS+sTCf8ZVQtZf2y1xYg==} + '@netlify/functions-utils@6.2.0': + resolution: {integrity: sha512-GCLjWKulGfDh7tfR28tz5lRoVBOQZL4SNac4XijCzZ2Sg93LfNUKSI9q+8yWEy5/wjNOEVp9nhZmrLoTtWpTdQ==} engines: {node: '>=18.14.0'} '@netlify/functions@4.1.4': @@ -2316,11 +2491,29 @@ packages: resolution: {integrity: sha512-MNYfEmZC6F7ZExOrB/Hrfkif7JW2Cbid9y5poTFEJ6rcAhCLQB8lo0SGlQrFXgKvXowXB14IjpOubaQu2zsyfg==} engines: {node: '>=18.0.0'} + '@netlify/serverless-functions-api@2.1.3': + resolution: {integrity: sha512-bNlN/hpND8xFQzpjyKxm6vJayD+bPBlOvs4lWihE7WULrphuH1UuFsoVE5386bNNGH8Rs1IH01AFsl7ALQgOlQ==} + engines: {node: '>=18.0.0'} + + '@netlify/types@2.0.2': + resolution: {integrity: sha512-6899BAqehToSAd3hoevqGaIkG0M9epPMLTi6byynNVIzqv2x+b9OtRXqK67G/gCX7XkrtLQ9Xm3QNJmaFNrSXA==} + engines: {node: ^18.14.0 || >=20} + '@netlify/zip-it-and-ship-it@12.1.4': resolution: {integrity: sha512-/wM1c0iyym/7SlowbgqTuu/+tJS8CDDs4vLhSizKntFl3VOeDVX0kr9qriH9wA2hYstwGSuHsEgEAnKdMcDBOg==} engines: {node: '>=18.14.0'} hasBin: true + '@netlify/zip-it-and-ship-it@14.0.0': + resolution: {integrity: sha512-bGSjyuU4m3EITjwTWg2fuGPwAxLJUijOs9SZSNRjMayhYzS+7B23GOi/oDWjZXq/thlyGO4jy25ruh02iW9pkg==} + engines: {node: '>=18.14.0'} + hasBin: true + + '@netlify/zip-it-and-ship-it@14.1.0': + resolution: {integrity: sha512-avFOrCOoRMCHfeZyVUNBAbP4Byi0FMYSWS2j4zn5KAbpBgOFRRc841JnGlXGB5gCIzsrJAsW5ZL8SnlXf6lrOQ==} + engines: {node: '>=18.14.0'} + hasBin: true + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -2337,8 +2530,8 @@ packages: resolution: {integrity: sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw==} engines: {node: '>= 18'} - '@octokit/core@6.1.5': - resolution: {integrity: sha512-vvmsN0r7rguA+FySiCsbaTTobSftpIDIpPW81trAmsv9TGxg3YCujAxRYp/Uy8xmDgYCzzgulG62H7KYUFmeIg==} + '@octokit/core@6.1.6': + resolution: {integrity: sha512-kIU8SLQkYWGp3pVKiYzA5OSaNF5EE03P/R8zEmmrG6XwOg5oBjXyQVVIauQ0dgau4zYhpZEhJrvIYt6oM+zZZA==} engines: {node: '>= 18'} '@octokit/endpoint@10.1.4': @@ -2748,201 +2941,101 @@ packages: cpu: [arm] os: [android] - '@rollup/rollup-android-arm-eabi@4.44.0': - resolution: {integrity: sha512-xEiEE5oDW6tK4jXCAyliuntGR+amEMO7HLtdSshVuhFnKTYoeYMyXQK7pLouAJJj5KHdwdn87bfHAR2nSdNAUA==} - cpu: [arm] - os: [android] - '@rollup/rollup-android-arm64@4.40.1': resolution: {integrity: sha512-PPkxTOisoNC6TpnDKatjKkjRMsdaWIhyuMkA4UsBXT9WEZY4uHezBTjs6Vl4PbqQQeu6oION1w2voYZv9yquCw==} cpu: [arm64] os: [android] - '@rollup/rollup-android-arm64@4.44.0': - resolution: {integrity: sha512-uNSk/TgvMbskcHxXYHzqwiyBlJ/lGcv8DaUfcnNwict8ba9GTTNxfn3/FAoFZYgkaXXAdrAA+SLyKplyi349Jw==} - cpu: [arm64] - os: [android] - '@rollup/rollup-darwin-arm64@4.40.1': resolution: {integrity: sha512-VWXGISWFY18v/0JyNUy4A46KCFCb9NVsH+1100XP31lud+TzlezBbz24CYzbnA4x6w4hx+NYCXDfnvDVO6lcAA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-arm64@4.44.0': - resolution: {integrity: sha512-VGF3wy0Eq1gcEIkSCr8Ke03CWT+Pm2yveKLaDvq51pPpZza3JX/ClxXOCmTYYq3us5MvEuNRTaeyFThCKRQhOA==} - cpu: [arm64] - os: [darwin] - '@rollup/rollup-darwin-x64@4.40.1': resolution: {integrity: sha512-nIwkXafAI1/QCS7pxSpv/ZtFW6TXcNUEHAIA9EIyw5OzxJZQ1YDrX+CL6JAIQgZ33CInl1R6mHet9Y/UZTg2Bw==} cpu: [x64] os: [darwin] - '@rollup/rollup-darwin-x64@4.44.0': - resolution: {integrity: sha512-fBkyrDhwquRvrTxSGH/qqt3/T0w5Rg0L7ZIDypvBPc1/gzjJle6acCpZ36blwuwcKD/u6oCE/sRWlUAcxLWQbQ==} - cpu: [x64] - os: [darwin] - '@rollup/rollup-freebsd-arm64@4.40.1': resolution: {integrity: sha512-BdrLJ2mHTrIYdaS2I99mriyJfGGenSaP+UwGi1kB9BLOCu9SR8ZpbkmmalKIALnRw24kM7qCN0IOm6L0S44iWw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-arm64@4.44.0': - resolution: {integrity: sha512-u5AZzdQJYJXByB8giQ+r4VyfZP+walV+xHWdaFx/1VxsOn6eWJhK2Vl2eElvDJFKQBo/hcYIBg/jaKS8ZmKeNQ==} - cpu: [arm64] - os: [freebsd] - '@rollup/rollup-freebsd-x64@4.40.1': resolution: {integrity: sha512-VXeo/puqvCG8JBPNZXZf5Dqq7BzElNJzHRRw3vjBE27WujdzuOPecDPc/+1DcdcTptNBep3861jNq0mYkT8Z6Q==} cpu: [x64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.44.0': - resolution: {integrity: sha512-qC0kS48c/s3EtdArkimctY7h3nHicQeEUdjJzYVJYR3ct3kWSafmn6jkNCA8InbUdge6PVx6keqjk5lVGJf99g==} - cpu: [x64] - os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.40.1': resolution: {integrity: sha512-ehSKrewwsESPt1TgSE/na9nIhWCosfGSFqv7vwEtjyAqZcvbGIg4JAcV7ZEh2tfj/IlfBeZjgOXm35iOOjadcg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-gnueabihf@4.44.0': - resolution: {integrity: sha512-x+e/Z9H0RAWckn4V2OZZl6EmV0L2diuX3QB0uM1r6BvhUIv6xBPL5mrAX2E3e8N8rEHVPwFfz/ETUbV4oW9+lQ==} - cpu: [arm] - os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.40.1': resolution: {integrity: sha512-m39iO/aaurh5FVIu/F4/Zsl8xppd76S4qoID8E+dSRQvTyZTOI2gVk3T4oqzfq1PtcvOfAVlwLMK3KRQMaR8lg==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.44.0': - resolution: {integrity: sha512-1exwiBFf4PU/8HvI8s80icyCcnAIB86MCBdst51fwFmH5dyeoWVPVgmQPcKrMtBQ0W5pAs7jBCWuRXgEpRzSCg==} - cpu: [arm] - os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.40.1': resolution: {integrity: sha512-Y+GHnGaku4aVLSgrT0uWe2o2Rq8te9hi+MwqGF9r9ORgXhmHK5Q71N757u0F8yU1OIwUIFy6YiJtKjtyktk5hg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.44.0': - resolution: {integrity: sha512-ZTR2mxBHb4tK4wGf9b8SYg0Y6KQPjGpR4UWwTFdnmjB4qRtoATZ5dWn3KsDwGa5Z2ZBOE7K52L36J9LueKBdOQ==} - cpu: [arm64] - os: [linux] - '@rollup/rollup-linux-arm64-musl@4.40.1': resolution: {integrity: sha512-jEwjn3jCA+tQGswK3aEWcD09/7M5wGwc6+flhva7dsQNRZZTe30vkalgIzV4tjkopsTS9Jd7Y1Bsj6a4lzz8gQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.44.0': - resolution: {integrity: sha512-GFWfAhVhWGd4r6UxmnKRTBwP1qmModHtd5gkraeW2G490BpFOZkFtem8yuX2NyafIP/mGpRJgTJ2PwohQkUY/Q==} - cpu: [arm64] - os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.40.1': resolution: {integrity: sha512-ySyWikVhNzv+BV/IDCsrraOAZ3UaC8SZB67FZlqVwXwnFhPihOso9rPOxzZbjp81suB1O2Topw+6Ug3JNegejQ==} cpu: [loong64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.44.0': - resolution: {integrity: sha512-xw+FTGcov/ejdusVOqKgMGW3c4+AgqrfvzWEVXcNP6zq2ue+lsYUgJ+5Rtn/OTJf7e2CbgTFvzLW2j0YAtj0Gg==} - cpu: [loong64] - os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.40.1': resolution: {integrity: sha512-BvvA64QxZlh7WZWqDPPdt0GH4bznuL6uOO1pmgPnnv86rpUpc8ZxgZwcEgXvo02GRIZX1hQ0j0pAnhwkhwPqWg==} cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.44.0': - resolution: {integrity: sha512-bKGibTr9IdF0zr21kMvkZT4K6NV+jjRnBoVMt2uNMG0BYWm3qOVmYnXKzx7UhwrviKnmK46IKMByMgvpdQlyJQ==} - cpu: [ppc64] - os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.40.1': resolution: {integrity: sha512-EQSP+8+1VuSulm9RKSMKitTav89fKbHymTf25n5+Yr6gAPZxYWpj3DzAsQqoaHAk9YX2lwEyAf9S4W8F4l3VBQ==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.44.0': - resolution: {integrity: sha512-vV3cL48U5kDaKZtXrti12YRa7TyxgKAIDoYdqSIOMOFBXqFj2XbChHAtXquEn2+n78ciFgr4KIqEbydEGPxXgA==} - cpu: [riscv64] - os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.40.1': resolution: {integrity: sha512-n/vQ4xRZXKuIpqukkMXZt9RWdl+2zgGNx7Uda8NtmLJ06NL8jiHxUawbwC+hdSq1rrw/9CghCpEONor+l1e2gA==} cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.44.0': - resolution: {integrity: sha512-TDKO8KlHJuvTEdfw5YYFBjhFts2TR0VpZsnLLSYmB7AaohJhM8ctDSdDnUGq77hUh4m/djRafw+9zQpkOanE2Q==} - cpu: [riscv64] - os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.40.1': resolution: {integrity: sha512-h8d28xzYb98fMQKUz0w2fMc1XuGzLLjdyxVIbhbil4ELfk5/orZlSTpF/xdI9C8K0I8lCkq+1En2RJsawZekkg==} cpu: [s390x] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.44.0': - resolution: {integrity: sha512-8541GEyktXaw4lvnGp9m84KENcxInhAt6vPWJ9RodsB/iGjHoMB2Pp5MVBCiKIRxrxzJhGCxmNzdu+oDQ7kwRA==} - cpu: [s390x] - os: [linux] - '@rollup/rollup-linux-x64-gnu@4.40.1': resolution: {integrity: sha512-XiK5z70PEFEFqcNj3/zRSz/qX4bp4QIraTy9QjwJAb/Z8GM7kVUsD0Uk8maIPeTyPCP03ChdI+VVmJriKYbRHQ==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.44.0': - resolution: {integrity: sha512-iUVJc3c0o8l9Sa/qlDL2Z9UP92UZZW1+EmQ4xfjTc1akr0iUFZNfxrXJ/R1T90h/ILm9iXEY6+iPrmYB3pXKjw==} - cpu: [x64] - os: [linux] - '@rollup/rollup-linux-x64-musl@4.40.1': resolution: {integrity: sha512-2BRORitq5rQ4Da9blVovzNCMaUlyKrzMSvkVR0D4qPuOy/+pMCrh1d7o01RATwVy+6Fa1WBw+da7QPeLWU/1mQ==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.44.0': - resolution: {integrity: sha512-PQUobbhLTQT5yz/SPg116VJBgz+XOtXt8D1ck+sfJJhuEsMj2jSej5yTdp8CvWBSceu+WW+ibVL6dm0ptG5fcA==} - cpu: [x64] - os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.40.1': resolution: {integrity: sha512-b2bcNm9Kbde03H+q+Jjw9tSfhYkzrDUf2d5MAd1bOJuVplXvFhWz7tRtWvD8/ORZi7qSCy0idW6tf2HgxSXQSg==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-arm64-msvc@4.44.0': - resolution: {integrity: sha512-M0CpcHf8TWn+4oTxJfh7LQuTuaYeXGbk0eageVjQCKzYLsajWS/lFC94qlRqOlyC2KvRT90ZrfXULYmukeIy7w==} - cpu: [arm64] - os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.40.1': resolution: {integrity: sha512-DfcogW8N7Zg7llVEfpqWMZcaErKfsj9VvmfSyRjCyo4BI3wPEfrzTtJkZG6gKP/Z92wFm6rz2aDO7/JfiR/whA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.44.0': - resolution: {integrity: sha512-3XJ0NQtMAXTWFW8FqZKcw3gOQwBtVWP/u8TpHP3CRPXD7Pd6s8lLdH3sHWh8vqKCyyiI8xW5ltJScQmBU9j7WA==} - cpu: [ia32] - os: [win32] - '@rollup/rollup-win32-x64-msvc@4.40.1': resolution: {integrity: sha512-ECyOuDeH3C1I8jH2MK1RtBJW+YPMvSfT0a5NN0nHfQYnDSJ6tUiZH3gzwVP5/Kfh/+Tt7tpWVF9LXNTnhTJ3kA==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.44.0': - resolution: {integrity: sha512-Q2Mgwt+D8hd5FIPUuPDsvPR7Bguza6yTkJxspDGkZj7tBRn2y4KSWYuIXpftFSjBra76TbKerCV7rgFPQrn+wQ==} - cpu: [x64] - os: [win32] - '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} @@ -3044,9 +3137,6 @@ packages: '@types/estree@1.0.7': resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/http-cache-semantics@4.0.4': resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} @@ -3455,33 +3545,6 @@ packages: bare-events@2.5.4: resolution: {integrity: sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==} - bare-fs@4.1.5: - resolution: {integrity: sha512-1zccWBMypln0jEE05LzZt+V/8y8AQsQQqxtklqaIyg5nu6OAYFhZxPXinJTSG+kU5qyNmeLgcn9AW7eHiCHVLA==} - engines: {bare: '>=1.16.0'} - peerDependencies: - bare-buffer: '*' - peerDependenciesMeta: - bare-buffer: - optional: true - - bare-os@3.6.1: - resolution: {integrity: sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==} - engines: {bare: '>=1.14.0'} - - bare-path@3.0.0: - resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} - - bare-stream@2.6.5: - resolution: {integrity: sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==} - peerDependencies: - bare-buffer: '*' - bare-events: '*' - peerDependenciesMeta: - bare-buffer: - optional: true - bare-events: - optional: true - base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -3498,10 +3561,6 @@ packages: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} @@ -3617,17 +3676,10 @@ packages: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} - chownr@1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - chownr@3.0.0: resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} engines: {node: '>=18'} @@ -3770,6 +3822,10 @@ packages: resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} engines: {node: ^14.18.0 || >=16.10.0} + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + console-clear@1.1.1: resolution: {integrity: sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ==} engines: {node: '>=4'} @@ -3843,8 +3899,8 @@ packages: crossws@0.3.5: resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} - css-select@5.1.0: - resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} css-tree@2.2.1: resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} @@ -3854,8 +3910,8 @@ packages: resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - css-what@6.1.0: - resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} engines: {node: '>= 6'} cssesc@3.0.0: @@ -3891,15 +3947,6 @@ packages: supports-color: optional: true - debug@4.4.0: - resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.4.1: resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} engines: {node: '>=6.0'} @@ -4175,6 +4222,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.25.6: + resolution: {integrity: sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -4327,10 +4379,6 @@ packages: resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} engines: {node: '>=6'} - expand-template@2.0.3: - resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} - engines: {node: '>=6'} - expect-type@1.2.1: resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} engines: {node: '>=12.0.0'} @@ -4548,9 +4596,6 @@ packages: from2@2.3.0: resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} - fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -4596,8 +4641,8 @@ packages: resolution: {integrity: sha512-LmCKVxioe63Fy6KDAQ/mmCSOSSRUE/x4zdrMD+7dU8quF3bGpzvP8mOmq4Dgce3nzU9AgkVDotucNOOg7c27BQ==} engines: {node: '>= 12.0.0'} - get-port-please@3.1.2: - resolution: {integrity: sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ==} + get-port-please@3.2.0: + resolution: {integrity: sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==} get-port@5.1.1: resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} @@ -4644,9 +4689,6 @@ packages: gitconfiglocal@2.1.0: resolution: {integrity: sha512-qoerOEliJn3z+Zyn1HW2F6eoYJqKwS6MgC9cztTLUB/xLWX8gD/6T60pKn4+t/d6tP7JlybI7Z3z+I572CR/Vg==} - github-from-package@0.0.0: - resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} - glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -4699,10 +4741,6 @@ packages: resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} engines: {node: '>=14.16'} - got@13.0.0: - resolution: {integrity: sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==} - engines: {node: '>=16'} - graceful-fs@4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} @@ -4735,8 +4773,12 @@ packages: resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} engines: {node: ^16.14.0 || >=18.0.0} - hot-shots@10.2.1: - resolution: {integrity: sha512-tmjcyZkG/qADhcdC7UjAp8D7v7W2DOYFgaZ48fYMuayMQmVVUg8fntKmrjes/b40ef6yZ+qt1lB8kuEDfLC4zw==} + hosted-git-info@8.1.0: + resolution: {integrity: sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==} + engines: {node: ^18.17.0 || >=20.5.0} + + hot-shots@11.1.0: + resolution: {integrity: sha512-D4iAs/145g7EJ/wIzBLVANEpysTPthUy/K+4EUIw02YJQTqvzD1vUpYiM3vwR0qPAQj4FhQpQz8wBpY8KDcM0g==} engines: {node: '>=10.0.0'} http-cache-semantics@4.2.0: @@ -4864,8 +4906,8 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - ipx@2.1.0: - resolution: {integrity: sha512-AVnPGXJ8L41vjd11Z4akIF2yd14636Klxul3tBySxHA6PKfCOQPxBDkCFK5zcWh0z/keR6toh1eg8qzdBVUgdA==} + ipx@3.0.3: + resolution: {integrity: sha512-c8ZWrM9Rzf8C/W1WoBb9KJ73C76+s3xyBL4iS5WdlPVIObE14tKKW79JIWbMkzhPZw71ZL/mLRMSvQOOhwbj0Q==} hasBin: true iron-webcrypto@1.2.1: @@ -4874,10 +4916,6 @@ packages: is-arrayish@0.3.2: resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - is-builtin-module@3.2.1: resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} engines: {node: '>=6'} @@ -5028,8 +5066,8 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - jiti@2.4.2: - resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} + jiti@2.5.1: + resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==} hasBin: true jpeg-js@0.4.4: @@ -5113,8 +5151,8 @@ packages: kuler@2.0.0: resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} - ky@1.8.1: - resolution: {integrity: sha512-7Bp3TpsE+L+TARSnnDpk3xg8Idi8RwSLdj6CMbNWoOARIrGrbuLGusV0dYwbZOm4bB3jHNxSw8Wk/ByDqJEnDw==} + ky@1.8.2: + resolution: {integrity: sha512-XybQJ3d4Ea1kI27DoelE5ZCT3bSJlibYTtQuMsyzKox3TMyayw1asgQdl54WroAm+fIA3ZCr8zXW2RpR7qWVpA==} engines: {node: '>=18'} lambda-local@2.2.0: @@ -5455,9 +5493,6 @@ packages: resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} engines: {node: '>= 18'} - mkdirp-classic@0.5.3: - resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - mkdirp@3.0.1: resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} engines: {node: '>=10'} @@ -5506,8 +5541,8 @@ packages: mute-stream@0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} - nan@2.22.2: - resolution: {integrity: sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==} + nan@2.23.0: + resolution: {integrity: sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==} nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} @@ -5517,9 +5552,6 @@ packages: nanospinner@1.2.2: resolution: {integrity: sha512-Zt/AmG6qRU3e+WnzGGLuMCEAO/dAu45stNbHY223tUxldaDAeE+FxSPsd9Q+j+paejmm0ZbrNVs5Sraqy3dRxA==} - napi-build-utils@2.0.0: - resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} - natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -5527,8 +5559,8 @@ packages: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} - netlify-cli@22.1.6: - resolution: {integrity: sha512-53yG96/bme20BdJ5uhBW06rLhfEps3AdimhNZ52Y2D09/Iu1DiIk+cTeFX87jL/9AsO8R7B1j7ma+sQboErzfw==} + netlify-cli@22.3.0: + resolution: {integrity: sha512-63J+xp2fmdUpJH58v+8c7PCKBg0DmNBtzPlzXf8GHDGg31N68zCgG12w+RBXC41tg8kHVK4wZi/ILzheD5pg8w==} engines: {node: '>=20.12.2'} hasBin: true @@ -5538,13 +5570,6 @@ packages: no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} - node-abi@3.75.0: - resolution: {integrity: sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==} - engines: {node: '>=10'} - - node-addon-api@6.1.0: - resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} - node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} @@ -5577,8 +5602,8 @@ packages: resolution: {integrity: sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==} hasBin: true - node-mock-http@1.0.0: - resolution: {integrity: sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ==} + node-mock-http@1.0.1: + resolution: {integrity: sha512-0gJJgENizp4ghds/Ywu2FCmcRsgBTmRQzYPZm61wy+Em2sBarSka0OhQS5huLBg6od1zkNpnWMCZloQDFVvOMQ==} node-source-walk@7.0.1: resolution: {integrity: sha512-3VW/8JpPqPvnJvseXowjZcirPisssnBuDikk6JIZ8jQzF7KJQX52iPFX4RYYxLycYH7IbMRSPUOga/esVjy5Yg==} @@ -5601,6 +5626,10 @@ packages: resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} engines: {node: ^16.14.0 || >=18.0.0} + normalize-package-data@7.0.0: + resolution: {integrity: sha512-k6U0gKRIuNCTkwHGZqblCfLfBRh+w1vI6tBo+IeJwq2M8FUiOqhX7GH+GArQGScA7azd1WfyRCvxoXDO3hQDIA==} + engines: {node: ^18.17.0 || >=20.5.0} + normalize-path@2.1.1: resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} engines: {node: '>=0.10.0'} @@ -5645,8 +5674,8 @@ packages: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} - on-headers@1.0.2: - resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} + on-headers@1.1.0: + resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} engines: {node: '>= 0.8'} once@1.4.0: @@ -5953,11 +5982,6 @@ packages: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} - prebuild-install@7.1.3: - resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} - engines: {node: '>=10'} - hasBin: true - precinct@12.2.0: resolution: {integrity: sha512-NFBMuwIfaJ4SocE9YXPU/n4AcNSoFMVFjP72nvl3cx69j/ke61/hPOWFREVxLkFhhEGnA8ZuVfTqJBa+PK3b5w==} engines: {node: '>=18'} @@ -6130,10 +6154,6 @@ packages: readdir-glob@1.1.3: resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - readdirp@4.0.1: resolution: {integrity: sha512-GkMg9uOTpIWWKbSsgwb5fA4EavTR+SG/PMPoAY8hkhHfEEY0/vqljY+XHqtDf2cr2IJtoNRDbrrEpZUiZCkYRw==} engines: {node: '>= 14.16.0'} @@ -6240,11 +6260,6 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - rollup@4.44.0: - resolution: {integrity: sha512-qHcdEzLCiktQIfwBq420pn2dP+30uzqYxv9ETm91wdt2R9AFcWfjNAmje4NWlnCIQ5RMTzVf0ZyisOKqHR6RwA==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - run-applescript@7.0.0: resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} engines: {node: '>=18'} @@ -6331,10 +6346,6 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - sharp@0.32.6: - resolution: {integrity: sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==} - engines: {node: '>=14.15.0'} - sharp@0.33.5: resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -6377,12 +6388,6 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - simple-concat@1.0.1: - resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} - - simple-get@4.0.1: - resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} - simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} @@ -6655,16 +6660,6 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} - tar-fs@2.1.3: - resolution: {integrity: sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==} - - tar-fs@3.0.10: - resolution: {integrity: sha512-C1SwlQGNLe/jPNqapK8epDsXME7CAJR5RL3GcE6KWx1d9OUByzoHVcbu1VPI8tevg9H8Alae0AApHHFGzrD5zA==} - - tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} - tar-stream@3.1.7: resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} @@ -6810,9 +6805,6 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -6853,8 +6845,8 @@ packages: resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==} engines: {node: '>= 0.8'} - ulid@3.0.0: - resolution: {integrity: sha512-yvZYdXInnJve6LdlPIuYmURdS2NP41ZoF4QW7SXwbUKYt53+0eDAySO+rGSvM2O/ciuB/G+8N7GQrZ1mCJpuqw==} + ulid@3.0.1: + resolution: {integrity: sha512-dPJyqPzx8preQhqq24bBG1YNkvigm87K8kVEHCD+ruZg24t6IFEFv00xMWfxcC4djmFtiTLdFuADn4+DOz6R7Q==} hasBin: true unbzip2-stream@1.4.3: @@ -6900,8 +6892,8 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - unstorage@1.16.0: - resolution: {integrity: sha512-WQ37/H5A7LcRPWfYOrDa1Ys02xAbpPJq6q5GkO88FBXVSQzHd7+BjEwfRqyaSWCv9MbsJy058GWjjPjcJ16GGA==} + unstorage@1.16.1: + resolution: {integrity: sha512-gdpZ3guLDhz+zWIlYP1UwQ259tG5T5vYRzDaHMkQ1bBY1SQPutvZnrRjTFaWUUpseErJIgAZS51h6NOcZVZiqQ==} peerDependencies: '@azure/app-configuration': ^1.8.0 '@azure/cosmos': ^4.2.0 @@ -6911,7 +6903,7 @@ packages: '@azure/storage-blob': ^12.26.0 '@capacitor/preferences': ^6.0.3 || ^7.0.0 '@deno/kv': '>=0.9.0' - '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 '@planetscale/database': ^1.19.0 '@upstash/redis': ^1.34.3 '@vercel/blob': '>=0.27.1' @@ -7199,8 +7191,8 @@ packages: utf-8-validate: optional: true - ws@8.18.2: - resolution: {integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==} + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -7312,6 +7304,16 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@babel/types@7.28.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + + '@babel/types@7.28.1': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@bugsnag/browser@8.4.0': dependencies: '@bugsnag/core': 8.4.0 @@ -7551,153 +7553,231 @@ snapshots: '@esbuild/aix-ppc64@0.25.5': optional: true + '@esbuild/aix-ppc64@0.25.6': + optional: true + '@esbuild/android-arm64@0.25.4': optional: true '@esbuild/android-arm64@0.25.5': optional: true + '@esbuild/android-arm64@0.25.6': + optional: true + '@esbuild/android-arm@0.25.4': optional: true '@esbuild/android-arm@0.25.5': optional: true + '@esbuild/android-arm@0.25.6': + optional: true + '@esbuild/android-x64@0.25.4': optional: true '@esbuild/android-x64@0.25.5': optional: true + '@esbuild/android-x64@0.25.6': + optional: true + '@esbuild/darwin-arm64@0.25.4': optional: true '@esbuild/darwin-arm64@0.25.5': optional: true + '@esbuild/darwin-arm64@0.25.6': + optional: true + '@esbuild/darwin-x64@0.25.4': optional: true '@esbuild/darwin-x64@0.25.5': optional: true + '@esbuild/darwin-x64@0.25.6': + optional: true + '@esbuild/freebsd-arm64@0.25.4': optional: true '@esbuild/freebsd-arm64@0.25.5': optional: true + '@esbuild/freebsd-arm64@0.25.6': + optional: true + '@esbuild/freebsd-x64@0.25.4': optional: true '@esbuild/freebsd-x64@0.25.5': optional: true + '@esbuild/freebsd-x64@0.25.6': + optional: true + '@esbuild/linux-arm64@0.25.4': optional: true '@esbuild/linux-arm64@0.25.5': optional: true + '@esbuild/linux-arm64@0.25.6': + optional: true + '@esbuild/linux-arm@0.25.4': optional: true '@esbuild/linux-arm@0.25.5': optional: true + '@esbuild/linux-arm@0.25.6': + optional: true + '@esbuild/linux-ia32@0.25.4': optional: true '@esbuild/linux-ia32@0.25.5': optional: true + '@esbuild/linux-ia32@0.25.6': + optional: true + '@esbuild/linux-loong64@0.25.4': optional: true '@esbuild/linux-loong64@0.25.5': optional: true + '@esbuild/linux-loong64@0.25.6': + optional: true + '@esbuild/linux-mips64el@0.25.4': optional: true '@esbuild/linux-mips64el@0.25.5': optional: true + '@esbuild/linux-mips64el@0.25.6': + optional: true + '@esbuild/linux-ppc64@0.25.4': optional: true '@esbuild/linux-ppc64@0.25.5': optional: true + '@esbuild/linux-ppc64@0.25.6': + optional: true + '@esbuild/linux-riscv64@0.25.4': optional: true '@esbuild/linux-riscv64@0.25.5': optional: true + '@esbuild/linux-riscv64@0.25.6': + optional: true + '@esbuild/linux-s390x@0.25.4': optional: true '@esbuild/linux-s390x@0.25.5': optional: true + '@esbuild/linux-s390x@0.25.6': + optional: true + '@esbuild/linux-x64@0.25.4': optional: true '@esbuild/linux-x64@0.25.5': optional: true + '@esbuild/linux-x64@0.25.6': + optional: true + '@esbuild/netbsd-arm64@0.25.4': optional: true '@esbuild/netbsd-arm64@0.25.5': optional: true + '@esbuild/netbsd-arm64@0.25.6': + optional: true + '@esbuild/netbsd-x64@0.25.4': optional: true '@esbuild/netbsd-x64@0.25.5': optional: true + '@esbuild/netbsd-x64@0.25.6': + optional: true + '@esbuild/openbsd-arm64@0.25.4': optional: true '@esbuild/openbsd-arm64@0.25.5': optional: true + '@esbuild/openbsd-arm64@0.25.6': + optional: true + '@esbuild/openbsd-x64@0.25.4': optional: true '@esbuild/openbsd-x64@0.25.5': optional: true + '@esbuild/openbsd-x64@0.25.6': + optional: true + + '@esbuild/openharmony-arm64@0.25.6': + optional: true + '@esbuild/sunos-x64@0.25.4': optional: true '@esbuild/sunos-x64@0.25.5': optional: true + '@esbuild/sunos-x64@0.25.6': + optional: true + '@esbuild/win32-arm64@0.25.4': optional: true '@esbuild/win32-arm64@0.25.5': optional: true + '@esbuild/win32-arm64@0.25.6': + optional: true + '@esbuild/win32-ia32@0.25.4': optional: true '@esbuild/win32-ia32@0.25.5': optional: true + '@esbuild/win32-ia32@0.25.6': + optional: true + '@esbuild/win32-x64@0.25.4': optional: true '@esbuild/win32-x64@0.25.5': optional: true - '@eslint-community/eslint-utils@4.7.0(eslint@9.29.0(jiti@2.4.2))': + '@esbuild/win32-x64@0.25.6': + optional: true + + '@eslint-community/eslint-utils@4.7.0(eslint@9.29.0(jiti@2.5.1))': dependencies: - eslint: 9.29.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.5.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -7745,6 +7825,8 @@ snapshots: '@fastify/accept-negotiator@1.1.0': {} + '@fastify/accept-negotiator@2.0.1': {} + '@fastify/ajv-compiler@3.6.0': dependencies: ajv: 8.17.1 @@ -8035,7 +8117,7 @@ snapshots: https-proxy-agent: 7.0.6(supports-color@10.0.0) node-fetch: 2.7.0 nopt: 8.0.0 - semver: 7.7.2 + semver: 7.7.1 tar: 7.4.3 transitivePeerDependencies: - encoding @@ -8052,9 +8134,9 @@ snapshots: '@netlify/binary-info@1.0.0': {} - '@netlify/blobs@10.0.1': + '@netlify/blobs@10.0.5': dependencies: - '@netlify/dev-utils': 3.2.1 + '@netlify/dev-utils': 3.3.0 '@netlify/runtime-utils': 2.1.0 '@netlify/blobs@9.1.6': @@ -8062,7 +8144,7 @@ snapshots: '@netlify/dev-utils': 3.2.0 '@netlify/runtime-utils': 2.1.0 - '@netlify/build-info@10.0.6': + '@netlify/build-info@10.0.7': dependencies: '@bugsnag/js': 8.4.0 '@iarna/toml': 2.2.5 @@ -8070,23 +8152,23 @@ snapshots: find-up: 7.0.0 minimatch: 9.0.5 read-pkg: 9.0.1 - semver: 7.7.1 + semver: 7.7.2 yaml: 2.8.0 yargs: 17.7.2 - '@netlify/build@33.4.6(@opentelemetry/api@1.8.0)(@types/node@18.19.119)(picomatch@4.0.2)': + '@netlify/build@34.2.5(@opentelemetry/api@1.8.0)(@types/node@18.19.119)(picomatch@4.0.2)(rollup@4.40.1)': dependencies: '@bugsnag/js': 8.4.0 - '@netlify/blobs': 10.0.1 + '@netlify/blobs': 10.0.5 '@netlify/cache-utils': 6.0.3 - '@netlify/config': 23.0.10 - '@netlify/edge-bundler': 14.0.6 - '@netlify/functions-utils': 6.0.10(supports-color@10.0.0) + '@netlify/config': 23.2.0 + '@netlify/edge-bundler': 14.2.2 + '@netlify/functions-utils': 6.2.0(rollup@4.40.1)(supports-color@10.0.0) '@netlify/git-utils': 6.0.2 '@netlify/opentelemetry-utils': 2.0.1(@opentelemetry/api@1.8.0) '@netlify/plugins-list': 6.80.0 '@netlify/run-utils': 6.0.2 - '@netlify/zip-it-and-ship-it': 12.1.4(supports-color@10.0.0) + '@netlify/zip-it-and-ship-it': 14.0.0(rollup@4.40.1)(supports-color@10.0.0) '@opentelemetry/api': 1.8.0 '@sindresorhus/slugify': 2.2.1 ansi-escapes: 7.0.0 @@ -8096,11 +8178,9 @@ snapshots: fdir: 6.4.6(picomatch@4.0.2) figures: 6.1.0 filter-obj: 6.1.0 - got: 13.0.0 - hot-shots: 10.2.1 + hot-shots: 11.1.0 indent-string: 5.0.0 is-plain-obj: 4.1.0 - js-yaml: 4.1.0 keep-func-props: 6.0.0 locate-path: 7.2.0 log-process-errors: 11.0.1 @@ -8124,7 +8204,7 @@ snapshots: resolve: 2.0.0-next.5 rfdc: 1.4.1 safe-json-stringify: 1.2.0 - semver: 7.7.1 + semver: 7.7.2 string-width: 7.2.0 strip-ansi: 7.1.0 supports-color: 10.0.0 @@ -8132,6 +8212,7 @@ snapshots: ts-node: 10.9.2(@types/node@18.19.119)(typescript@5.8.3) typescript: 5.8.3 uuid: 11.1.0 + yaml: 2.8.0 yargs: 17.7.2 transitivePeerDependencies: - '@swc/core' @@ -8152,7 +8233,7 @@ snapshots: path-exists: 5.0.0 readdirp: 4.1.2 - '@netlify/config@23.0.10': + '@netlify/config@23.2.0': dependencies: '@iarna/toml': 2.2.5 '@netlify/api': 14.0.3 @@ -8169,13 +8250,14 @@ snapshots: find-up: 7.0.0 indent-string: 5.0.0 is-plain-obj: 4.1.0 - js-yaml: 4.1.0 map-obj: 5.0.2 omit.js: 2.0.2 p-locate: 6.0.0 path-type: 6.0.0 + read-package-up: 11.0.0 tomlify-j0.4: 3.0.0 validate-npm-package-name: 5.0.1 + yaml: 2.8.0 yargs: 17.7.2 '@netlify/dev-utils@3.2.0': @@ -8194,7 +8276,7 @@ snapshots: uuid: 11.1.0 write-file-atomic: 5.0.1 - '@netlify/dev-utils@3.2.1': + '@netlify/dev-utils@3.3.0': dependencies: '@whatwg-node/server': 0.10.10 ansis: 4.1.0 @@ -8208,10 +8290,29 @@ snapshots: lodash.debounce: 4.0.8 parse-gitignore: 2.0.0 semver: 7.7.2 + tmp-promise: 3.0.3 uuid: 11.1.0 write-file-atomic: 5.0.1 - '@netlify/edge-bundler@14.0.6': + '@netlify/dev-utils@4.1.0': + dependencies: + '@whatwg-node/server': 0.10.10 + ansis: 4.1.0 + chokidar: 4.0.3 + decache: 4.6.2 + dot-prop: 9.0.0 + env-paths: 3.0.0 + find-up: 7.0.0 + image-size: 2.0.2 + js-image-generator: 1.0.4 + lodash.debounce: 4.0.8 + parse-gitignore: 2.0.0 + semver: 7.7.2 + tmp-promise: 3.0.3 + uuid: 11.1.0 + write-file-atomic: 5.0.1 + + '@netlify/edge-bundler@14.2.2': dependencies: '@import-maps/resolve': 2.0.0 ajv: 8.17.1 @@ -8219,7 +8320,7 @@ snapshots: better-ajv-errors: 1.2.0(ajv@8.17.1) common-path-prefix: 3.0.0 env-paths: 3.0.0 - esbuild: 0.25.5 + esbuild: 0.25.6 execa: 8.0.1 find-up: 7.0.0 get-package-name: 2.2.0 @@ -8235,19 +8336,29 @@ snapshots: urlpattern-polyfill: 8.0.2 uuid: 11.1.0 - '@netlify/edge-functions-bootstrap@2.13.0': {} + '@netlify/edge-functions-bootstrap@2.14.0': {} - '@netlify/edge-functions@2.15.1': + '@netlify/edge-functions@2.15.7': dependencies: - '@netlify/dev-utils': 3.2.1 - '@netlify/edge-bundler': 14.0.6 - '@netlify/edge-functions-bootstrap': 2.13.0 + '@netlify/dev-utils': 3.3.0 + '@netlify/edge-bundler': 14.2.2 + '@netlify/edge-functions-bootstrap': 2.14.0 '@netlify/runtime-utils': 2.1.0 + '@netlify/types': 2.0.2 get-port: 7.1.0 - '@netlify/functions-utils@6.0.10(supports-color@10.0.0)': + '@netlify/edge-functions@2.16.2': dependencies: - '@netlify/zip-it-and-ship-it': 12.1.4(supports-color@10.0.0) + '@netlify/dev-utils': 4.1.0 + '@netlify/edge-bundler': 14.2.2 + '@netlify/edge-functions-bootstrap': 2.14.0 + '@netlify/runtime-utils': 2.1.0 + '@netlify/types': 2.0.2 + get-port: 7.1.0 + + '@netlify/functions-utils@6.2.0(rollup@4.40.1)(supports-color@10.0.0)': + dependencies: + '@netlify/zip-it-and-ship-it': 14.1.0(rollup@4.40.1)(supports-color@10.0.0) cpy: 11.1.0 path-exists: 5.0.0 transitivePeerDependencies: @@ -8366,13 +8477,17 @@ snapshots: '@netlify/serverless-functions-api@2.1.1': {} - '@netlify/zip-it-and-ship-it@12.1.4': + '@netlify/serverless-functions-api@2.1.3': {} + + '@netlify/types@2.0.2': {} + + '@netlify/zip-it-and-ship-it@12.1.4(rollup@4.40.1)': dependencies: '@babel/parser': 7.27.5 '@babel/types': 7.27.6 '@netlify/binary-info': 1.0.0 '@netlify/serverless-functions-api': 2.1.1 - '@vercel/nft': 0.29.4(supports-color@10.0.0) + '@vercel/nft': 0.29.4(rollup@4.40.1)(supports-color@10.0.0) archiver: 7.0.1 common-path-prefix: 3.0.0 copy-file: 11.0.0 @@ -8406,18 +8521,18 @@ snapshots: - rollup - supports-color - '@netlify/zip-it-and-ship-it@12.1.4(rollup@4.40.1)': + '@netlify/zip-it-and-ship-it@14.0.0(rollup@4.40.1)(supports-color@10.0.0)': dependencies: '@babel/parser': 7.27.5 - '@babel/types': 7.27.6 + '@babel/types': 7.28.0 '@netlify/binary-info': 1.0.0 - '@netlify/serverless-functions-api': 2.1.1 - '@vercel/nft': 0.29.4(rollup@4.40.1) + '@netlify/serverless-functions-api': 2.1.3 + '@vercel/nft': 0.29.4(rollup@4.40.1)(supports-color@10.0.0) archiver: 7.0.1 common-path-prefix: 3.0.0 copy-file: 11.0.0 es-module-lexer: 1.7.0 - esbuild: 0.25.5 + esbuild: 0.25.6 execa: 8.0.1 fast-glob: 3.3.3 filter-obj: 6.1.0 @@ -8434,7 +8549,7 @@ snapshots: precinct: 12.2.0(supports-color@10.0.0) require-package-name: 2.0.1 resolve: 2.0.0-next.5 - semver: 7.7.1 + semver: 7.7.2 tmp-promise: 3.0.3 toml: 3.0.0 unixify: 1.0.0 @@ -8446,18 +8561,18 @@ snapshots: - rollup - supports-color - '@netlify/zip-it-and-ship-it@12.1.4(supports-color@10.0.0)': + '@netlify/zip-it-and-ship-it@14.1.0(rollup@4.40.1)(supports-color@10.0.0)': dependencies: '@babel/parser': 7.27.5 - '@babel/types': 7.27.6 + '@babel/types': 7.28.1 '@netlify/binary-info': 1.0.0 - '@netlify/serverless-functions-api': 2.1.1 - '@vercel/nft': 0.29.4(supports-color@10.0.0) + '@netlify/serverless-functions-api': 2.1.3 + '@vercel/nft': 0.29.4(rollup@4.40.1)(supports-color@10.0.0) archiver: 7.0.1 common-path-prefix: 3.0.0 copy-file: 11.0.0 es-module-lexer: 1.7.0 - esbuild: 0.25.5 + esbuild: 0.25.6 execa: 8.0.1 fast-glob: 3.3.3 filter-obj: 6.1.0 @@ -8474,7 +8589,7 @@ snapshots: precinct: 12.2.0(supports-color@10.0.0) require-package-name: 2.0.1 resolve: 2.0.0-next.5 - semver: 7.7.1 + semver: 7.7.2 tmp-promise: 3.0.3 toml: 3.0.0 unixify: 1.0.0 @@ -8500,7 +8615,7 @@ snapshots: '@octokit/auth-token@5.1.2': {} - '@octokit/core@6.1.5': + '@octokit/core@6.1.6': dependencies: '@octokit/auth-token': 5.1.2 '@octokit/graphql': 8.2.2 @@ -8525,18 +8640,18 @@ snapshots: '@octokit/openapi-types@25.1.0': {} - '@octokit/plugin-paginate-rest@11.6.0(@octokit/core@6.1.5)': + '@octokit/plugin-paginate-rest@11.6.0(@octokit/core@6.1.6)': dependencies: - '@octokit/core': 6.1.5 + '@octokit/core': 6.1.6 '@octokit/types': 13.10.0 - '@octokit/plugin-request-log@5.3.1(@octokit/core@6.1.5)': + '@octokit/plugin-request-log@5.3.1(@octokit/core@6.1.6)': dependencies: - '@octokit/core': 6.1.5 + '@octokit/core': 6.1.6 - '@octokit/plugin-rest-endpoint-methods@13.5.0(@octokit/core@6.1.5)': + '@octokit/plugin-rest-endpoint-methods@13.5.0(@octokit/core@6.1.6)': dependencies: - '@octokit/core': 6.1.5 + '@octokit/core': 6.1.6 '@octokit/types': 13.10.0 '@octokit/request-error@6.1.8': @@ -8553,10 +8668,10 @@ snapshots: '@octokit/rest@21.1.1': dependencies: - '@octokit/core': 6.1.5 - '@octokit/plugin-paginate-rest': 11.6.0(@octokit/core@6.1.5) - '@octokit/plugin-request-log': 5.3.1(@octokit/core@6.1.5) - '@octokit/plugin-rest-endpoint-methods': 13.5.0(@octokit/core@6.1.5) + '@octokit/core': 6.1.6 + '@octokit/plugin-paginate-rest': 11.6.0(@octokit/core@6.1.6) + '@octokit/plugin-request-log': 5.3.1(@octokit/core@6.1.6) + '@octokit/plugin-rest-endpoint-methods': 13.5.0(@octokit/core@6.1.6) '@octokit/types@13.10.0': dependencies: @@ -8951,134 +9066,66 @@ snapshots: optionalDependencies: rollup: 4.40.1 - '@rollup/pluginutils@5.1.3(rollup@4.44.0)': - dependencies: - '@types/estree': 1.0.7 - estree-walker: 2.0.2 - picomatch: 4.0.2 - optionalDependencies: - rollup: 4.44.0 - '@rollup/rollup-android-arm-eabi@4.40.1': optional: true - '@rollup/rollup-android-arm-eabi@4.44.0': - optional: true - '@rollup/rollup-android-arm64@4.40.1': optional: true - '@rollup/rollup-android-arm64@4.44.0': - optional: true - '@rollup/rollup-darwin-arm64@4.40.1': optional: true - '@rollup/rollup-darwin-arm64@4.44.0': - optional: true - '@rollup/rollup-darwin-x64@4.40.1': optional: true - '@rollup/rollup-darwin-x64@4.44.0': - optional: true - '@rollup/rollup-freebsd-arm64@4.40.1': optional: true - '@rollup/rollup-freebsd-arm64@4.44.0': - optional: true - '@rollup/rollup-freebsd-x64@4.40.1': optional: true - '@rollup/rollup-freebsd-x64@4.44.0': - optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.40.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.44.0': - optional: true - '@rollup/rollup-linux-arm-musleabihf@4.40.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.44.0': - optional: true - '@rollup/rollup-linux-arm64-gnu@4.40.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.44.0': - optional: true - '@rollup/rollup-linux-arm64-musl@4.40.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.44.0': - optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.40.1': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.44.0': - optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.40.1': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.44.0': - optional: true - '@rollup/rollup-linux-riscv64-gnu@4.40.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.44.0': - optional: true - '@rollup/rollup-linux-riscv64-musl@4.40.1': optional: true - '@rollup/rollup-linux-riscv64-musl@4.44.0': - optional: true - '@rollup/rollup-linux-s390x-gnu@4.40.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.44.0': - optional: true - '@rollup/rollup-linux-x64-gnu@4.40.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.44.0': - optional: true - '@rollup/rollup-linux-x64-musl@4.40.1': optional: true - '@rollup/rollup-linux-x64-musl@4.44.0': - optional: true - '@rollup/rollup-win32-arm64-msvc@4.40.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.44.0': - optional: true - '@rollup/rollup-win32-ia32-msvc@4.40.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.44.0': - optional: true - '@rollup/rollup-win32-x64-msvc@4.40.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.44.0': - optional: true - '@sec-ant/readable-stream@0.4.1': {} '@sindresorhus/is@5.6.0': {} @@ -9094,11 +9141,11 @@ snapshots: dependencies: escape-string-regexp: 5.0.0 - '@stylistic/eslint-plugin-js@2.1.0(eslint@9.29.0(jiti@2.4.2))': + '@stylistic/eslint-plugin-js@2.1.0(eslint@9.29.0(jiti@2.5.1))': dependencies: '@types/eslint': 8.56.12 acorn: 8.15.0 - eslint: 9.29.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.5.1) eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -9110,36 +9157,36 @@ snapshots: dependencies: acorn: 8.15.0 - '@sveltejs/eslint-config@8.2.0(@stylistic/eslint-plugin-js@2.1.0(eslint@9.29.0(jiti@2.4.2)))(eslint-config-prettier@9.1.0(eslint@9.29.0(jiti@2.4.2)))(eslint-plugin-n@17.16.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-svelte@3.9.3(eslint@9.29.0(jiti@2.4.2))(svelte@5.35.5)(ts-node@10.9.2(@types/node@18.19.119)(typescript@5.8.3)))(eslint@9.29.0(jiti@2.4.2))(typescript-eslint@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(typescript@5.8.3)': + '@sveltejs/eslint-config@8.2.0(@stylistic/eslint-plugin-js@2.1.0(eslint@9.29.0(jiti@2.5.1)))(eslint-config-prettier@9.1.0(eslint@9.29.0(jiti@2.5.1)))(eslint-plugin-n@17.16.1(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3))(eslint-plugin-svelte@3.9.3(eslint@9.29.0(jiti@2.5.1))(svelte@5.35.5)(ts-node@10.9.2(@types/node@18.19.119)(typescript@5.8.3)))(eslint@9.29.0(jiti@2.5.1))(typescript-eslint@8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3))(typescript@5.8.3)': dependencies: - '@stylistic/eslint-plugin-js': 2.1.0(eslint@9.29.0(jiti@2.4.2)) - eslint: 9.29.0(jiti@2.4.2) - eslint-config-prettier: 9.1.0(eslint@9.29.0(jiti@2.4.2)) - eslint-plugin-n: 17.16.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) - eslint-plugin-svelte: 3.9.3(eslint@9.29.0(jiti@2.4.2))(svelte@5.35.5)(ts-node@10.9.2(@types/node@18.19.119)(typescript@5.8.3)) + '@stylistic/eslint-plugin-js': 2.1.0(eslint@9.29.0(jiti@2.5.1)) + eslint: 9.29.0(jiti@2.5.1) + eslint-config-prettier: 9.1.0(eslint@9.29.0(jiti@2.5.1)) + eslint-plugin-n: 17.16.1(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3) + eslint-plugin-svelte: 3.9.3(eslint@9.29.0(jiti@2.5.1))(svelte@5.35.5)(ts-node@10.9.2(@types/node@18.19.119)(typescript@5.8.3)) globals: 15.15.0 typescript: 5.8.3 - typescript-eslint: 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + typescript-eslint: 8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3) - '@sveltejs/vite-plugin-svelte-inspector@5.0.0-next.0(@sveltejs/vite-plugin-svelte@6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.0-next.0(@sveltejs/vite-plugin-svelte@6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + '@sveltejs/vite-plugin-svelte': 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) debug: 4.4.1(supports-color@10.0.0) svelte: 5.35.5 - vite: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + vite: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': + '@sveltejs/vite-plugin-svelte@6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.0-next.0(@sveltejs/vite-plugin-svelte@6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.0-next.0(@sveltejs/vite-plugin-svelte@6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) debug: 4.4.1(supports-color@10.0.0) deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.17 svelte: 5.35.5 - vite: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) - vitefu: 1.1.1(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + vite: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) + vitefu: 1.1.1(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) transitivePeerDependencies: - supports-color @@ -9180,13 +9227,11 @@ snapshots: '@types/eslint@8.56.12': dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.7 '@types/json-schema': 7.0.15 '@types/estree@1.0.7': {} - '@types/estree@1.0.8': {} - '@types/http-cache-semantics@4.0.4': {} '@types/http-proxy@1.17.16': @@ -9220,15 +9265,15 @@ snapshots: '@types/node': 18.19.119 optional: true - '@typescript-eslint/eslint-plugin@8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/eslint-plugin@8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3) '@typescript-eslint/scope-manager': 8.35.0 - '@typescript-eslint/type-utils': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/type-utils': 8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3) '@typescript-eslint/visitor-keys': 8.35.0 - eslint: 9.29.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.5.1) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -9237,14 +9282,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3)': dependencies: '@typescript-eslint/scope-manager': 8.35.0 '@typescript-eslint/types': 8.35.0 '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) '@typescript-eslint/visitor-keys': 8.35.0 debug: 4.4.1(supports-color@10.0.0) - eslint: 9.29.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.5.1) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -9267,12 +9312,12 @@ snapshots: dependencies: typescript: 5.8.3 - '@typescript-eslint/type-utils@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/type-utils@8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3)': dependencies: '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) - '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3) debug: 4.4.1(supports-color@10.0.0) - eslint: 9.29.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.5.1) ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: @@ -9290,7 +9335,7 @@ snapshots: fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.2 + semver: 7.7.1 ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: @@ -9306,19 +9351,19 @@ snapshots: fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.2 + semver: 7.7.1 ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': + '@typescript-eslint/utils@8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.5.1)) '@typescript-eslint/scope-manager': 8.35.0 '@typescript-eslint/types': 8.35.0 '@typescript-eslint/typescript-estree': 8.35.0(typescript@5.8.3) - eslint: 9.29.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.5.1) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -9333,7 +9378,7 @@ snapshots: '@typescript-eslint/types': 8.35.0 eslint-visitor-keys: 4.2.1 - '@vercel/nft@0.29.4(rollup@4.40.1)': + '@vercel/nft@0.29.4(rollup@4.40.1)(supports-color@10.0.0)': dependencies: '@mapbox/node-pre-gyp': 2.0.0(supports-color@10.0.0) '@rollup/pluginutils': 5.1.3(rollup@4.40.1) @@ -9352,29 +9397,10 @@ snapshots: - rollup - supports-color - '@vercel/nft@0.29.4(supports-color@10.0.0)': - dependencies: - '@mapbox/node-pre-gyp': 2.0.0(supports-color@10.0.0) - '@rollup/pluginutils': 5.1.3(rollup@4.44.0) - acorn: 8.15.0 - acorn-import-attributes: 1.9.5(acorn@8.15.0) - async-sema: 3.1.1 - bindings: 1.5.0 - estree-walker: 2.0.2 - glob: 10.4.5 - graceful-fs: 4.2.11 - node-gyp-build: 4.8.0 - picomatch: 4.0.2 - resolve-from: 5.0.0 - transitivePeerDependencies: - - encoding - - rollup - - supports-color - - '@vercel/nft@0.30.0(rollup@4.44.0)': + '@vercel/nft@0.30.0(rollup@4.40.1)': dependencies: '@mapbox/node-pre-gyp': 2.0.0(supports-color@10.0.0) - '@rollup/pluginutils': 5.1.3(rollup@4.44.0) + '@rollup/pluginutils': 5.1.3(rollup@4.40.1) acorn: 8.15.0 acorn-import-attributes: 1.9.5(acorn@8.15.0) async-sema: 3.1.1 @@ -9398,13 +9424,13 @@ snapshots: chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.3(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': + '@vitest/mocker@3.2.3(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0))': dependencies: '@vitest/spy': 3.2.3 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + vite: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) '@vitest/pretty-format@3.2.3': dependencies: @@ -9563,10 +9589,6 @@ snapshots: dependencies: acorn: 8.15.0 - acorn-import-attributes@1.9.5(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -9717,28 +9739,6 @@ snapshots: bare-events@2.5.4: optional: true - bare-fs@4.1.5: - dependencies: - bare-events: 2.5.4 - bare-path: 3.0.0 - bare-stream: 2.6.5(bare-events@2.5.4) - optional: true - - bare-os@3.6.1: - optional: true - - bare-path@3.0.0: - dependencies: - bare-os: 3.6.1 - optional: true - - bare-stream@2.6.5(bare-events@2.5.4): - dependencies: - streamx: 2.22.1 - optionalDependencies: - bare-events: 2.5.4 - optional: true - base64-js@1.5.1: {} before-after-hook@3.0.2: {} @@ -9756,8 +9756,6 @@ snapshots: dependencies: is-windows: 1.0.2 - binary-extensions@2.3.0: {} - bindings@1.5.0: dependencies: file-uri-to-path: 1.0.0 @@ -9890,24 +9888,10 @@ snapshots: check-error@2.1.1: {} - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - chokidar@4.0.3: dependencies: readdirp: 4.0.1 - chownr@1.1.4: {} - chownr@3.0.0: {} ci-info@3.9.0: {} @@ -9916,7 +9900,7 @@ snapshots: citty@0.1.6: dependencies: - consola: 3.2.3 + consola: 3.4.2 cjs-module-lexer@1.4.3: {} @@ -10042,6 +10026,8 @@ snapshots: consola@3.2.3: {} + consola@3.4.2: {} + console-clear@1.1.1: {} content-disposition@0.5.4: @@ -10105,10 +10091,10 @@ snapshots: dependencies: uncrypto: 0.1.3 - css-select@5.1.0: + css-select@5.2.2: dependencies: boolbase: 1.0.0 - css-what: 6.1.0 + css-what: 6.2.2 domhandler: 5.0.3 domutils: 3.2.2 nth-check: 2.1.1 @@ -10123,7 +10109,7 @@ snapshots: mdn-data: 2.0.30 source-map-js: 1.2.1 - css-what@6.1.0: {} + css-what@6.2.2: {} cssesc@3.0.0: {} @@ -10145,10 +10131,6 @@ snapshots: dependencies: ms: 2.0.0 - debug@4.4.0: - dependencies: - ms: 2.1.3 - debug@4.4.1(supports-color@10.0.0): dependencies: ms: 2.1.3 @@ -10434,6 +10416,35 @@ snapshots: '@esbuild/win32-ia32': 0.25.5 '@esbuild/win32-x64': 0.25.5 + esbuild@0.25.6: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.6 + '@esbuild/android-arm': 0.25.6 + '@esbuild/android-arm64': 0.25.6 + '@esbuild/android-x64': 0.25.6 + '@esbuild/darwin-arm64': 0.25.6 + '@esbuild/darwin-x64': 0.25.6 + '@esbuild/freebsd-arm64': 0.25.6 + '@esbuild/freebsd-x64': 0.25.6 + '@esbuild/linux-arm': 0.25.6 + '@esbuild/linux-arm64': 0.25.6 + '@esbuild/linux-ia32': 0.25.6 + '@esbuild/linux-loong64': 0.25.6 + '@esbuild/linux-mips64el': 0.25.6 + '@esbuild/linux-ppc64': 0.25.6 + '@esbuild/linux-riscv64': 0.25.6 + '@esbuild/linux-s390x': 0.25.6 + '@esbuild/linux-x64': 0.25.6 + '@esbuild/netbsd-arm64': 0.25.6 + '@esbuild/netbsd-x64': 0.25.6 + '@esbuild/openbsd-arm64': 0.25.6 + '@esbuild/openbsd-x64': 0.25.6 + '@esbuild/openharmony-arm64': 0.25.6 + '@esbuild/sunos-x64': 0.25.6 + '@esbuild/win32-arm64': 0.25.6 + '@esbuild/win32-ia32': 0.25.6 + '@esbuild/win32-x64': 0.25.6 + escalade@3.2.0: {} escape-goat@4.0.0: {} @@ -10454,51 +10465,51 @@ snapshots: optionalDependencies: source-map: 0.6.1 - eslint-compat-utils@0.5.1(eslint@9.29.0(jiti@2.4.2)): + eslint-compat-utils@0.5.1(eslint@9.29.0(jiti@2.5.1)): dependencies: - eslint: 9.29.0(jiti@2.4.2) - semver: 7.7.2 + eslint: 9.29.0(jiti@2.5.1) + semver: 7.7.1 - eslint-config-prettier@9.1.0(eslint@9.29.0(jiti@2.4.2)): + eslint-config-prettier@9.1.0(eslint@9.29.0(jiti@2.5.1)): dependencies: - eslint: 9.29.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.5.1) - eslint-plugin-es-x@7.8.0(eslint@9.29.0(jiti@2.4.2)): + eslint-plugin-es-x@7.8.0(eslint@9.29.0(jiti@2.5.1)): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.5.1)) '@eslint-community/regexpp': 4.12.1 - eslint: 9.29.0(jiti@2.4.2) - eslint-compat-utils: 0.5.1(eslint@9.29.0(jiti@2.4.2)) + eslint: 9.29.0(jiti@2.5.1) + eslint-compat-utils: 0.5.1(eslint@9.29.0(jiti@2.5.1)) - eslint-plugin-n@17.16.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3): + eslint-plugin-n@17.16.1(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) - '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.5.1)) + '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3) enhanced-resolve: 5.18.1 - eslint: 9.29.0(jiti@2.4.2) - eslint-plugin-es-x: 7.8.0(eslint@9.29.0(jiti@2.4.2)) + eslint: 9.29.0(jiti@2.5.1) + eslint-plugin-es-x: 7.8.0(eslint@9.29.0(jiti@2.5.1)) get-tsconfig: 4.10.0 globals: 15.15.0 ignore: 5.3.2 minimatch: 9.0.5 - semver: 7.7.2 + semver: 7.7.1 ts-declaration-location: 1.0.7(typescript@5.8.3) transitivePeerDependencies: - supports-color - typescript - eslint-plugin-svelte@3.9.3(eslint@9.29.0(jiti@2.4.2))(svelte@5.35.5)(ts-node@10.9.2(@types/node@18.19.119)(typescript@5.8.3)): + eslint-plugin-svelte@3.9.3(eslint@9.29.0(jiti@2.5.1))(svelte@5.35.5)(ts-node@10.9.2(@types/node@18.19.119)(typescript@5.8.3)): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.5.1)) '@jridgewell/sourcemap-codec': 1.5.0 - eslint: 9.29.0(jiti@2.4.2) + eslint: 9.29.0(jiti@2.5.1) esutils: 2.0.3 globals: 16.2.0 known-css-properties: 0.37.0 postcss: 8.5.6 postcss-load-config: 3.1.4(postcss@8.5.6)(ts-node@10.9.2(@types/node@18.19.119)(typescript@5.8.3)) postcss-safe-parser: 7.0.1(postcss@8.5.6) - semver: 7.7.2 + semver: 7.7.1 svelte-eslint-parser: 1.2.0(svelte@5.35.5) optionalDependencies: svelte: 5.35.5 @@ -10516,9 +10527,9 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.29.0(jiti@2.4.2): + eslint@9.29.0(jiti@2.5.1): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.5.1)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.20.1 '@eslint/config-helpers': 0.2.3 @@ -10554,7 +10565,7 @@ snapshots: natural-compare: 1.4.0 optionator: 0.9.3 optionalDependencies: - jiti: 2.4.2 + jiti: 2.5.1 transitivePeerDependencies: - supports-color @@ -10586,7 +10597,7 @@ snapshots: estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.7 esutils@2.0.3: {} @@ -10624,13 +10635,11 @@ snapshots: exit-hook@2.2.1: {} - expand-template@2.0.3: {} - expect-type@1.2.1: {} express-logging@1.1.1: dependencies: - on-headers: 1.0.2 + on-headers: 1.1.0 express@4.21.2: dependencies: @@ -10763,7 +10772,7 @@ snapshots: proxy-addr: 2.0.7 rfdc: 1.4.1 secure-json-parse: 2.7.0 - semver: 7.7.1 + semver: 7.7.2 toad-cache: 3.7.0 fastq@1.17.1: @@ -10868,9 +10877,9 @@ snapshots: dependencies: from2: 2.3.0 - follow-redirects@1.15.9(debug@4.4.0): + follow-redirects@1.15.9(debug@4.4.1): optionalDependencies: - debug: 4.4.0 + debug: 4.4.1(supports-color@10.0.0) foreground-child@3.3.0: dependencies: @@ -10892,8 +10901,6 @@ snapshots: inherits: 2.0.4 readable-stream: 2.3.8 - fs-constants@1.0.0: {} - fs-extra@7.0.1: dependencies: graceful-fs: 4.2.11 @@ -10940,7 +10947,7 @@ snapshots: get-package-name@2.2.0: {} - get-port-please@3.1.2: {} + get-port-please@3.2.0: {} get-port@5.1.1: {} @@ -10977,7 +10984,7 @@ snapshots: dependencies: '@xhmikosr/downloader': 13.0.1 node-fetch: 3.3.2 - semver: 7.7.1 + semver: 7.7.2 git-repo-info@2.1.1: {} @@ -10985,8 +10992,6 @@ snapshots: dependencies: ini: 1.3.8 - github-from-package@0.0.0: {} - glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -11054,20 +11059,6 @@ snapshots: p-cancelable: 3.0.0 responselike: 3.0.0 - got@13.0.0: - dependencies: - '@sindresorhus/is': 5.6.0 - '@szmarczak/http-timer': 5.0.1 - cacheable-lookup: 7.0.0 - cacheable-request: 10.2.14 - decompress-response: 6.0.0 - form-data-encoder: 2.1.4 - get-stream: 6.0.1 - http2-wrapper: 2.2.1 - lowercase-keys: 3.0.0 - p-cancelable: 3.0.0 - responselike: 3.0.0 - graceful-fs@4.2.10: {} graceful-fs@4.2.11: {} @@ -11081,7 +11072,7 @@ snapshots: defu: 6.1.4 destr: 2.0.5 iron-webcrypto: 1.2.1 - node-mock-http: 1.0.0 + node-mock-http: 1.0.1 radix3: 1.1.2 ufo: 1.6.1 uncrypto: 0.1.3 @@ -11100,7 +11091,11 @@ snapshots: dependencies: lru-cache: 10.4.3 - hot-shots@10.2.1: + hosted-git-info@8.1.0: + dependencies: + lru-cache: 10.4.3 + + hot-shots@11.1.0: optionalDependencies: unix-dgram: 2.0.6 @@ -11122,20 +11117,20 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 - http-proxy-middleware@2.0.9(debug@4.4.0): + http-proxy-middleware@2.0.9(debug@4.4.1): dependencies: '@types/http-proxy': 1.17.16 - http-proxy: 1.18.1(debug@4.4.0) + http-proxy: 1.18.1(debug@4.4.1) is-glob: 4.0.3 is-plain-obj: 3.0.0 micromatch: 4.0.8 transitivePeerDependencies: - debug - http-proxy@1.18.1(debug@4.4.0): + http-proxy@1.18.1(debug@4.4.1): dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.9(debug@4.4.0) + follow-redirects: 1.15.9(debug@4.4.1) requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -11237,11 +11232,11 @@ snapshots: ipaddr.js@1.9.1: {} - ipx@2.1.0(@netlify/blobs@9.1.6): + ipx@3.0.3(@netlify/blobs@10.0.5): dependencies: - '@fastify/accept-negotiator': 1.1.0 + '@fastify/accept-negotiator': 2.0.1 citty: 0.1.6 - consola: 3.2.3 + consola: 3.4.2 defu: 6.1.4 destr: 2.0.5 etag: 1.8.1 @@ -11249,11 +11244,11 @@ snapshots: image-meta: 0.2.1 listhen: 1.9.0 ofetch: 1.4.1 - pathe: 1.1.2 - sharp: 0.32.6 + pathe: 2.0.3 + sharp: 0.33.5 svgo: 3.3.2 ufo: 1.6.1 - unstorage: 1.16.0(@netlify/blobs@9.1.6) + unstorage: 1.16.1(@netlify/blobs@10.0.5) xss: 1.0.15 transitivePeerDependencies: - '@azure/app-configuration' @@ -11270,7 +11265,6 @@ snapshots: - '@vercel/blob' - '@vercel/kv' - aws4fetch - - bare-buffer - db0 - idb-keyval - ioredis @@ -11280,10 +11274,6 @@ snapshots: is-arrayish@0.3.2: {} - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - is-builtin-module@3.2.1: dependencies: builtin-modules: 3.3.0 @@ -11389,7 +11379,7 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 - jiti@2.4.2: {} + jiti@2.5.1: {} jpeg-js@0.4.4: {} @@ -11439,7 +11429,7 @@ snapshots: lodash.isstring: 4.0.1 lodash.once: 4.1.1 ms: 2.1.3 - semver: 7.7.1 + semver: 7.7.2 junk@4.0.1: {} @@ -11472,7 +11462,7 @@ snapshots: kuler@2.0.0: {} - ky@1.8.1: {} + ky@1.8.2: {} lambda-local@2.2.0: dependencies: @@ -11555,13 +11545,13 @@ snapshots: '@parcel/watcher-wasm': 2.5.1 citty: 0.1.6 clipboardy: 4.0.0 - consola: 3.2.3 + consola: 3.4.2 crossws: 0.3.5 defu: 6.1.4 - get-port-please: 3.1.2 + get-port-please: 3.2.0 h3: 1.15.3 http-shutdown: 1.2.2 - jiti: 2.4.2 + jiti: 2.5.1 mlly: 1.7.4 node-forge: 1.3.1 pathe: 1.1.2 @@ -11774,8 +11764,6 @@ snapshots: dependencies: minipass: 7.1.2 - mkdirp-classic@0.5.3: {} - mkdirp@3.0.1: {} mlly@1.7.4: @@ -11819,7 +11807,7 @@ snapshots: mute-stream@0.0.8: {} - nan@2.22.2: + nan@2.23.0: optional: true nanoid@3.3.11: {} @@ -11828,26 +11816,25 @@ snapshots: dependencies: picocolors: 1.1.1 - napi-build-utils@2.0.0: {} - natural-compare@1.4.0: {} negotiator@0.6.3: {} - netlify-cli@22.1.6(@types/node@18.19.119)(picomatch@4.0.2): + netlify-cli@22.3.0(@types/node@18.19.119)(picomatch@4.0.2)(rollup@4.40.1): dependencies: '@fastify/static': 7.0.4 '@netlify/api': 14.0.3 - '@netlify/blobs': 9.1.6 - '@netlify/build': 33.4.6(@opentelemetry/api@1.8.0)(@types/node@18.19.119)(picomatch@4.0.2) - '@netlify/build-info': 10.0.6 - '@netlify/config': 23.0.10 - '@netlify/edge-bundler': 14.0.6 - '@netlify/edge-functions': 2.15.1 + '@netlify/blobs': 10.0.5 + '@netlify/build': 34.2.5(@opentelemetry/api@1.8.0)(@types/node@18.19.119)(picomatch@4.0.2)(rollup@4.40.1) + '@netlify/build-info': 10.0.7 + '@netlify/config': 23.2.0 + '@netlify/dev-utils': 3.3.0 + '@netlify/edge-bundler': 14.2.2 + '@netlify/edge-functions': 2.15.7 '@netlify/headers-parser': 9.0.1 '@netlify/local-functions-proxy': 2.0.3 '@netlify/redirect-parser': 15.0.2 - '@netlify/zip-it-and-ship-it': 12.1.4 + '@netlify/zip-it-and-ship-it': 14.0.0(rollup@4.40.1)(supports-color@10.0.0) '@octokit/rest': 21.1.1 '@opentelemetry/api': 1.8.0 '@pnpm/tabtab': 0.5.4 @@ -11857,7 +11844,7 @@ snapshots: backoff: 2.5.0 boxen: 8.0.1 chalk: 5.4.1 - chokidar: 3.6.0 + chokidar: 4.0.3 ci-info: 4.2.0 clean-deep: 3.4.0 commander: 12.1.0 @@ -11865,7 +11852,7 @@ snapshots: content-type: 1.0.5 cookie: 1.0.2 cron-parser: 4.9.0 - debug: 4.4.0 + debug: 4.4.1(supports-color@10.0.0) decache: 4.6.2 dot-prop: 9.0.0 dotenv: 16.5.0 @@ -11885,12 +11872,12 @@ snapshots: gh-release-fetch: 4.0.3 git-repo-info: 2.1.1 gitconfiglocal: 2.1.0 - http-proxy: 1.18.1(debug@4.4.0) - http-proxy-middleware: 2.0.9(debug@4.4.0) + http-proxy: 1.18.1(debug@4.4.1) + http-proxy-middleware: 2.0.9(debug@4.4.1) https-proxy-agent: 7.0.6(supports-color@10.0.0) inquirer: 8.2.6 inquirer-autocomplete-prompt: 1.4.0(inquirer@8.2.6) - ipx: 2.1.0(@netlify/blobs@9.1.6) + ipx: 3.0.3(@netlify/blobs@10.0.5) is-docker: 3.0.0 is-stream: 4.0.1 is-wsl: 3.1.0 @@ -11907,7 +11894,7 @@ snapshots: nanospinner: 1.2.2 netlify-redirector: 0.5.0 node-fetch: 3.3.2 - normalize-package-data: 6.0.2 + normalize-package-data: 7.0.0 open: 10.1.2 p-filter: 4.1.0 p-map: 7.0.3 @@ -11919,17 +11906,17 @@ snapshots: raw-body: 3.0.0 read-package-up: 11.0.0 readdirp: 4.1.2 - semver: 7.7.1 + semver: 7.7.2 source-map-support: 0.5.21 terminal-link: 4.0.0 toml: 3.0.0 tomlify-j0.4: 3.0.0 - ulid: 3.0.0 + ulid: 3.0.1 update-notifier: 7.3.1 uuid: 11.1.0 wait-port: 1.1.0 write-file-atomic: 5.0.1 - ws: 8.18.2 + ws: 8.18.3 transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -11949,7 +11936,6 @@ snapshots: - '@vercel/blob' - '@vercel/kv' - aws4fetch - - bare-buffer - bufferutil - db0 - encoding @@ -11968,12 +11954,6 @@ snapshots: lower-case: 2.0.2 tslib: 2.8.1 - node-abi@3.75.0: - dependencies: - semver: 7.7.2 - - node-addon-api@6.1.0: {} - node-addon-api@7.1.1: {} node-domexception@1.0.0: {} @@ -11994,7 +11974,7 @@ snapshots: node-gyp-build@4.8.0: {} - node-mock-http@1.0.0: {} + node-mock-http@1.0.1: {} node-source-walk@7.0.1: dependencies: @@ -12017,6 +11997,12 @@ snapshots: semver: 7.7.1 validate-npm-package-license: 3.0.4 + normalize-package-data@7.0.0: + dependencies: + hosted-git-info: 8.1.0 + semver: 7.7.2 + validate-npm-package-license: 3.0.4 + normalize-path@2.1.1: dependencies: remove-trailing-separator: 1.1.0 @@ -12055,7 +12041,7 @@ snapshots: dependencies: ee-first: 1.1.1 - on-headers@1.0.2: {} + on-headers@1.1.0: {} once@1.4.0: dependencies: @@ -12190,7 +12176,7 @@ snapshots: package-json@10.0.1: dependencies: - ky: 1.8.1 + ky: 1.8.2 registry-auth-token: 5.1.0 registry-url: 6.0.1 semver: 7.7.2 @@ -12354,21 +12340,6 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - prebuild-install@7.1.3: - dependencies: - detect-libc: 2.0.3 - expand-template: 2.0.3 - github-from-package: 0.0.0 - minimist: 1.2.8 - mkdirp-classic: 0.5.3 - napi-build-utils: 2.0.0 - node-abi: 3.75.0 - pump: 3.0.2 - rc: 1.2.8 - simple-get: 4.0.1 - tar-fs: 2.1.3 - tunnel-agent: 0.6.0 - precinct@12.2.0(supports-color@10.0.0): dependencies: '@dependents/detective-less': 5.0.1 @@ -12571,10 +12542,6 @@ snapshots: dependencies: minimatch: 5.1.6 - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - readdirp@4.0.1: {} readdirp@4.1.2: {} @@ -12681,32 +12648,6 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.40.1 fsevents: 2.3.3 - rollup@4.44.0: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.44.0 - '@rollup/rollup-android-arm64': 4.44.0 - '@rollup/rollup-darwin-arm64': 4.44.0 - '@rollup/rollup-darwin-x64': 4.44.0 - '@rollup/rollup-freebsd-arm64': 4.44.0 - '@rollup/rollup-freebsd-x64': 4.44.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.44.0 - '@rollup/rollup-linux-arm-musleabihf': 4.44.0 - '@rollup/rollup-linux-arm64-gnu': 4.44.0 - '@rollup/rollup-linux-arm64-musl': 4.44.0 - '@rollup/rollup-linux-loongarch64-gnu': 4.44.0 - '@rollup/rollup-linux-powerpc64le-gnu': 4.44.0 - '@rollup/rollup-linux-riscv64-gnu': 4.44.0 - '@rollup/rollup-linux-riscv64-musl': 4.44.0 - '@rollup/rollup-linux-s390x-gnu': 4.44.0 - '@rollup/rollup-linux-x64-gnu': 4.44.0 - '@rollup/rollup-linux-x64-musl': 4.44.0 - '@rollup/rollup-win32-arm64-msvc': 4.44.0 - '@rollup/rollup-win32-ia32-msvc': 4.44.0 - '@rollup/rollup-win32-x64-msvc': 4.44.0 - fsevents: 2.3.3 - run-applescript@7.0.0: {} run-async@2.4.1: {} @@ -12792,19 +12733,6 @@ snapshots: setprototypeof@1.2.0: {} - sharp@0.32.6: - dependencies: - color: 4.2.3 - detect-libc: 2.0.3 - node-addon-api: 6.1.0 - prebuild-install: 7.1.3 - semver: 7.7.2 - simple-get: 4.0.1 - tar-fs: 3.0.10 - tunnel-agent: 0.6.0 - transitivePeerDependencies: - - bare-buffer - sharp@0.33.5: dependencies: color: 4.2.3 @@ -12830,7 +12758,6 @@ snapshots: '@img/sharp-wasm32': 0.33.5 '@img/sharp-win32-ia32': 0.33.5 '@img/sharp-win32-x64': 0.33.5 - optional: true sharp@0.34.1: dependencies: @@ -12899,14 +12826,6 @@ snapshots: signal-exit@4.1.0: {} - simple-concat@1.0.1: {} - - simple-get@4.0.1: - dependencies: - decompress-response: 6.0.0 - once: 1.4.0 - simple-concat: 1.0.1 - simple-swizzle@0.2.2: dependencies: is-arrayish: 0.3.2 @@ -13161,9 +13080,9 @@ snapshots: dependencies: '@trysound/sax': 0.2.0 commander: 7.2.0 - css-select: 5.1.0 + css-select: 5.2.2 css-tree: 2.3.1 - css-what: 6.1.0 + css-what: 6.2.2 csso: 5.0.5 picocolors: 1.1.1 @@ -13171,31 +13090,6 @@ snapshots: tapable@2.2.1: {} - tar-fs@2.1.3: - dependencies: - chownr: 1.1.4 - mkdirp-classic: 0.5.3 - pump: 3.0.2 - tar-stream: 2.2.0 - - tar-fs@3.0.10: - dependencies: - pump: 3.0.2 - tar-stream: 3.1.7 - optionalDependencies: - bare-fs: 4.1.5 - bare-path: 3.0.0 - transitivePeerDependencies: - - bare-buffer - - tar-stream@2.2.0: - dependencies: - bl: 4.1.0 - end-of-stream: 1.4.4 - fs-constants: 1.0.0 - inherits: 2.0.4 - readable-stream: 3.6.2 - tar-stream@3.1.7: dependencies: b4a: 1.6.7 @@ -13347,10 +13241,6 @@ snapshots: tslib@2.8.1: {} - tunnel-agent@0.6.0: - dependencies: - safe-buffer: 5.2.1 - type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -13364,12 +13254,12 @@ snapshots: media-typer: 0.3.0 mime-types: 2.1.35 - typescript-eslint@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3): + typescript-eslint@8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) - eslint: 9.29.0(jiti@2.4.2) + '@typescript-eslint/eslint-plugin': 8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3) + '@typescript-eslint/parser': 8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.0(eslint@9.29.0(jiti@2.5.1))(typescript@5.8.3) + eslint: 9.29.0(jiti@2.5.1) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -13384,7 +13274,7 @@ snapshots: dependencies: random-bytes: 1.0.0 - ulid@3.0.0: {} + ulid@3.0.1: {} unbzip2-stream@1.4.3: dependencies: @@ -13418,7 +13308,7 @@ snapshots: unix-dgram@2.0.6: dependencies: bindings: 1.5.0 - nan: 2.22.2 + nan: 2.23.0 optional: true unixify@1.0.0: @@ -13427,7 +13317,7 @@ snapshots: unpipe@1.0.0: {} - unstorage@1.16.0(@netlify/blobs@9.1.6): + unstorage@1.16.1(@netlify/blobs@10.0.5): dependencies: anymatch: 3.1.3 chokidar: 4.0.3 @@ -13438,14 +13328,14 @@ snapshots: ofetch: 1.4.1 ufo: 1.6.1 optionalDependencies: - '@netlify/blobs': 9.1.6 + '@netlify/blobs': 10.0.5 untildify@4.0.0: {} untun@0.1.3: dependencies: citty: 0.1.6 - consola: 3.2.3 + consola: 3.4.2 pathe: 1.1.2 update-notifier@7.3.1: @@ -13458,7 +13348,7 @@ snapshots: is-npm: 6.0.0 latest-version: 9.0.0 pupa: 3.1.0 - semver: 7.7.1 + semver: 7.7.2 xdg-basedir: 5.1.0 uqr@0.1.2: {} @@ -13503,13 +13393,13 @@ snapshots: transitivePeerDependencies: - rollup - vite-node@3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0): + vite-node@3.2.3(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0): dependencies: cac: 6.7.14 debug: 4.4.1(supports-color@10.0.0) es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + vite: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) transitivePeerDependencies: - '@types/node' - jiti @@ -13524,30 +13414,30 @@ snapshots: - tsx - yaml - vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0): + vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0): dependencies: esbuild: 0.25.5 fdir: 6.4.6(picomatch@4.0.2) picomatch: 4.0.2 postcss: 8.5.6 - rollup: 4.44.0 + rollup: 4.40.1 tinyglobby: 0.2.14 optionalDependencies: '@types/node': 18.19.119 fsevents: 2.3.3 - jiti: 2.4.2 + jiti: 2.5.1 lightningcss: 1.30.1 yaml: 2.8.0 - vitefu@1.1.1(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)): + vitefu@1.1.1(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)): optionalDependencies: - vite: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + vite: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) - vitest@3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0): + vitest@3.2.3(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.3 - '@vitest/mocker': 3.2.3(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + '@vitest/mocker': 3.2.3(vite@6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0)) '@vitest/pretty-format': 3.2.3 '@vitest/runner': 3.2.3 '@vitest/snapshot': 3.2.3 @@ -13565,8 +13455,8 @@ snapshots: tinyglobby: 0.2.14 tinypool: 1.1.0 tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) - vite-node: 3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + vite: 6.3.5(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) + vite-node: 3.2.3(@types/node@18.19.119)(jiti@2.5.1)(lightningcss@1.30.1)(yaml@2.8.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 18.19.119 @@ -13708,7 +13598,7 @@ snapshots: ws@8.18.0: {} - ws@8.18.2: {} + ws@8.18.3: {} xdg-basedir@5.1.0: {} From fc3f73409ecbe4e30f7a6d5196f485b4c8967730 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 24 Jul 2025 13:37:00 -0600 Subject: [PATCH 14/74] fix dumb import analysis --- packages/kit/src/runtime/utils.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/kit/src/runtime/utils.js b/packages/kit/src/runtime/utils.js index 9b1aa19387ad..d8893919435e 100644 --- a/packages/kit/src/runtime/utils.js +++ b/packages/kit/src/runtime/utils.js @@ -1,5 +1,3 @@ -/** @import { Span } from '@opentelemetry/api'; */ - /** * @param {string} text * @returns {ArrayBufferLike} @@ -57,9 +55,9 @@ export function get_relative_path(from, to) { } /** - * @template {{ tracing: { enabled: boolean, root: Span, current: Span } }} T + * @template {{ tracing: { enabled: boolean, root: import('@opentelemetry/api').Span, current: import('@opentelemetry/api').Span } }} T * @param {T} event_like - * @param {Span} current + * @param {import('@opentelemetry/api').Span} current * @returns {T} */ export function merge_tracing(event_like, current) { From 4b64316a775f4400c31e8db1d223e68e7d9c64bd Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 24 Jul 2025 13:38:26 -0600 Subject: [PATCH 15/74] changeset --- .changeset/early-taxis-make.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/early-taxis-make.md diff --git a/.changeset/early-taxis-make.md b/.changeset/early-taxis-make.md new file mode 100644 index 000000000000..c21656024abc --- /dev/null +++ b/.changeset/early-taxis-make.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': minor +--- + +feat: OpenTelemetry tracing for `handle`, `sequence`, form actions, and `load` functions running on the server From b6b7d6af2109b905d4198ebfeb227db8b9bc19e8 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Wed, 6 Aug 2025 17:11:44 -0600 Subject: [PATCH 16/74] fix: conflict --- packages/kit/test/apps/basics/svelte.config.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/kit/test/apps/basics/svelte.config.js b/packages/kit/test/apps/basics/svelte.config.js index 42ef8d06b6b9..f5861fcefdbd 100644 --- a/packages/kit/test/apps/basics/svelte.config.js +++ b/packages/kit/test/apps/basics/svelte.config.js @@ -19,7 +19,10 @@ const config = { }, experimental: { - remoteFunctions: true + remoteFunctions: true, + tracing: { + server: true + } }, prerender: { @@ -44,9 +47,7 @@ const config = { router: { resolution: /** @type {'client' | 'server'} */ (process.env.ROUTER_RESOLUTION) || 'client' - }, - - experimental: { tracing: { server: true } } + } } }; From 60540cef0003718cd75cdd16d12dfb0baf7ca61d Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Wed, 6 Aug 2025 17:25:38 -0600 Subject: [PATCH 17/74] i do not know why this fixed it but it did --- packages/enhanced-img/package.json | 2 +- pnpm-lock.yaml | 120 ++++++++++++++++++----------- pnpm-workspace.yaml | 1 + 3 files changed, 79 insertions(+), 44 deletions(-) diff --git a/packages/enhanced-img/package.json b/packages/enhanced-img/package.json index 8c9e0fb98f3d..ec967187bb46 100644 --- a/packages/enhanced-img/package.json +++ b/packages/enhanced-img/package.json @@ -45,7 +45,7 @@ "devDependencies": { "@sveltejs/vite-plugin-svelte": "catalog:", "@types/estree": "^1.0.5", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "rollup": "^4.27.4", "svelte": "^5.35.5", "typescript": "^5.6.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5cef23407b38..4b70f9856b78 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,6 +12,9 @@ catalogs: '@sveltejs/vite-plugin-svelte': specifier: ^6.0.0-next.3 version: 6.0.0-next.3 + '@types/node': + specifier: ^18.19.119 + version: 18.19.119 cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -204,7 +207,7 @@ importers: version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) netlify-cli: specifier: ^23.0.0 - version: 23.1.1(@types/node@20.19.9)(picomatch@4.0.3)(rollup@4.44.0) + version: 23.1.1(@types/node@20.19.9)(picomatch@4.0.3) svelte: specifier: ^5.23.1 version: 5.35.5 @@ -222,7 +225,7 @@ importers: version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) netlify-cli: specifier: ^23.0.0 - version: 23.1.1(@types/node@20.19.9)(picomatch@4.0.3)(rollup@4.44.0) + version: 23.1.1(@types/node@20.19.9)(picomatch@4.0.3) svelte: specifier: ^5.23.1 version: 5.35.5 @@ -340,7 +343,7 @@ importers: dependencies: '@vercel/nft': specifier: ^0.30.0 - version: 0.30.0(rollup@4.44.0)(supports-color@10.1.0) + version: 0.30.0(rollup@4.44.0) esbuild: specifier: ^0.25.4 version: 0.25.5 @@ -397,7 +400,7 @@ importers: specifier: ^1.0.5 version: 1.0.8 '@types/node': - specifier: ^18.19.119 + specifier: 'catalog:' version: 18.19.119 rollup: specifier: ^4.27.4 @@ -3317,10 +3320,6 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.37.0': - resolution: {integrity: sha512-0vGq0yiU1gbjKob2q691ybTg9JX6ShiVXAAfm2jGf3q0hdP6/BruaFjL/ManAR/lj05AvYCH+5bbVo0VtzmjOA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.39.0': resolution: {integrity: sha512-8QOzff9UKxOh6npZQ/4FQu4mjdOCGSdO3p44ww0hk8Vu+IGbg0tB/H1LcTARRDzGCC8pDGbh2rissBuuoPgH8A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3364,13 +3363,6 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.37.0': - resolution: {integrity: sha512-TSFvkIW6gGjN2p6zbXo20FzCABbyUAuq6tBvNRGsKdsSQ6a7rnV6ADfZ7f4iI3lIiXc4F4WWvtUfDw9CJ9pO5A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/utils@8.39.0': resolution: {integrity: sha512-4GVSvNA0Vx1Ktwvf4sFE+exxJ3QGUorQG1/A5mRfRNZtkBT2xrA/BCO2H0eALx/PnvCS6/vmYwRdDA41EoffkQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -8373,19 +8365,19 @@ snapshots: yaml: 2.8.0 yargs: 17.7.2 - '@netlify/build@35.0.3(@opentelemetry/api@1.8.0)(@types/node@20.19.9)(picomatch@4.0.3)(rollup@4.44.0)': + '@netlify/build@35.0.3(@opentelemetry/api@1.8.0)(@types/node@20.19.9)(picomatch@4.0.3)': dependencies: '@bugsnag/js': 8.4.0 '@netlify/blobs': 10.0.8 '@netlify/cache-utils': 6.0.3 '@netlify/config': 24.0.1 '@netlify/edge-bundler': 14.4.1 - '@netlify/functions-utils': 6.2.1(rollup@4.44.0)(supports-color@10.1.0) + '@netlify/functions-utils': 6.2.1(supports-color@10.1.0) '@netlify/git-utils': 6.0.2 '@netlify/opentelemetry-utils': 2.0.1(@opentelemetry/api@1.8.0) '@netlify/plugins-list': 6.80.0 '@netlify/run-utils': 6.0.2 - '@netlify/zip-it-and-ship-it': 14.1.1(rollup@4.44.0)(supports-color@10.1.0) + '@netlify/zip-it-and-ship-it': 14.1.1(supports-color@10.1.0) '@opentelemetry/api': 1.8.0 '@sindresorhus/slugify': 2.2.1 ansi-escapes: 7.0.0 @@ -8566,9 +8558,9 @@ snapshots: '@netlify/types': 2.0.2 get-port: 7.1.0 - '@netlify/functions-utils@6.2.1(rollup@4.44.0)(supports-color@10.1.0)': + '@netlify/functions-utils@6.2.1(supports-color@10.1.0)': dependencies: - '@netlify/zip-it-and-ship-it': 14.1.1(rollup@4.44.0)(supports-color@10.1.0) + '@netlify/zip-it-and-ship-it': 14.1.1(supports-color@10.1.0) cpy: 11.1.0 path-exists: 5.0.0 transitivePeerDependencies: @@ -8730,13 +8722,52 @@ snapshots: - rollup - supports-color - '@netlify/zip-it-and-ship-it@14.1.1(rollup@4.44.0)(supports-color@10.1.0)': + '@netlify/zip-it-and-ship-it@14.1.1': dependencies: '@babel/parser': 7.27.5 '@babel/types': 7.28.1 '@netlify/binary-info': 1.0.0 '@netlify/serverless-functions-api': 2.1.3 - '@vercel/nft': 0.30.0(rollup@4.44.0)(supports-color@10.1.0) + '@vercel/nft': 0.30.0(rollup@4.44.0) + archiver: 7.0.1 + common-path-prefix: 3.0.0 + copy-file: 11.0.0 + es-module-lexer: 1.7.0 + esbuild: 0.25.6 + execa: 8.0.1 + fast-glob: 3.3.3 + filter-obj: 6.1.0 + find-up: 7.0.0 + is-path-inside: 4.0.0 + junk: 4.0.1 + locate-path: 7.2.0 + merge-options: 3.0.4 + minimatch: 9.0.5 + normalize-path: 3.0.0 + p-map: 7.0.3 + path-exists: 5.0.0 + precinct: 12.2.0(supports-color@10.1.0) + require-package-name: 2.0.1 + resolve: 2.0.0-next.5 + semver: 7.7.2 + tmp-promise: 3.0.3 + toml: 3.0.0 + unixify: 1.0.0 + urlpattern-polyfill: 8.0.2 + yargs: 17.7.2 + zod: 3.25.56 + transitivePeerDependencies: + - encoding + - rollup + - supports-color + + '@netlify/zip-it-and-ship-it@14.1.1(supports-color@10.1.0)': + dependencies: + '@babel/parser': 7.27.5 + '@babel/types': 7.28.1 + '@netlify/binary-info': 1.0.0 + '@netlify/serverless-functions-api': 2.1.3 + '@vercel/nft': 0.30.0(supports-color@10.1.0) archiver: 7.0.1 common-path-prefix: 3.0.0 copy-file: 11.0.0 @@ -9502,11 +9533,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.37.0': - dependencies: - '@typescript-eslint/types': 8.37.0 - '@typescript-eslint/visitor-keys': 8.37.0 - '@typescript-eslint/scope-manager@8.39.0': dependencies: '@typescript-eslint/types': 8.39.0 @@ -9568,17 +9594,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.37.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) - '@typescript-eslint/scope-manager': 8.37.0 - '@typescript-eslint/types': 8.37.0 - '@typescript-eslint/typescript-estree': 8.37.0(supports-color@10.1.0)(typescript@5.8.3) - eslint: 9.29.0(jiti@2.4.2) - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/utils@8.39.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) @@ -9619,7 +9634,26 @@ snapshots: - rollup - supports-color - '@vercel/nft@0.30.0(rollup@4.44.0)(supports-color@10.1.0)': + '@vercel/nft@0.30.0(rollup@4.44.0)': + dependencies: + '@mapbox/node-pre-gyp': 2.0.0(supports-color@10.1.0) + '@rollup/pluginutils': 5.1.3(rollup@4.44.0) + acorn: 8.15.0 + acorn-import-attributes: 1.9.5(acorn@8.15.0) + async-sema: 3.1.1 + bindings: 1.5.0 + estree-walker: 2.0.2 + glob: 10.4.5 + graceful-fs: 4.2.11 + node-gyp-build: 4.8.0 + picomatch: 4.0.3 + resolve-from: 5.0.0 + transitivePeerDependencies: + - encoding + - rollup + - supports-color + + '@vercel/nft@0.30.0(supports-color@10.1.0)': dependencies: '@mapbox/node-pre-gyp': 2.0.0(supports-color@10.1.0) '@rollup/pluginutils': 5.1.3(rollup@4.44.0) @@ -10718,7 +10752,7 @@ snapshots: eslint-plugin-n@17.16.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3): dependencies: '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) - '@typescript-eslint/utils': 8.37.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.39.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) enhanced-resolve: 5.18.2 eslint: 9.29.0(jiti@2.4.2) eslint-plugin-es-x: 7.8.0(eslint@9.29.0(jiti@2.4.2)) @@ -12052,12 +12086,12 @@ snapshots: negotiator@0.6.3: {} - netlify-cli@23.1.1(@types/node@20.19.9)(picomatch@4.0.3)(rollup@4.44.0): + netlify-cli@23.1.1(@types/node@20.19.9)(picomatch@4.0.3): dependencies: '@fastify/static': 7.0.4 '@netlify/api': 14.0.3 '@netlify/blobs': 10.0.8 - '@netlify/build': 35.0.3(@opentelemetry/api@1.8.0)(@types/node@20.19.9)(picomatch@4.0.3)(rollup@4.44.0) + '@netlify/build': 35.0.3(@opentelemetry/api@1.8.0)(@types/node@20.19.9)(picomatch@4.0.3) '@netlify/build-info': 10.0.7 '@netlify/config': 24.0.1 '@netlify/dev-utils': 4.1.1 @@ -12066,7 +12100,7 @@ snapshots: '@netlify/headers-parser': 9.0.1 '@netlify/local-functions-proxy': 2.0.3 '@netlify/redirect-parser': 15.0.3 - '@netlify/zip-it-and-ship-it': 14.1.1(rollup@4.44.0)(supports-color@10.1.0) + '@netlify/zip-it-and-ship-it': 14.1.1 '@octokit/rest': 21.1.1 '@opentelemetry/api': 1.8.0 '@pnpm/tabtab': 0.5.4 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 5552fdfb0ded..c520b3835bcb 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -14,6 +14,7 @@ packages: catalog: '@playwright/test': '^1.51.1' '@sveltejs/vite-plugin-svelte': '^6.0.0-next.3' + '@types/node': '^18.19.119' 'cross-env': '^7.0.3' 'vitest': '^3.2.3' 'vite': '^6.3.5' From 091eaef53689f9e10f6bfa4d407e9531db54f01d Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 7 Aug 2025 13:01:48 -0600 Subject: [PATCH 18/74] idk man --- packages/enhanced-img/package.json | 2 +- pnpm-lock.yaml | 5 +---- pnpm-workspace.yaml | 1 - 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/enhanced-img/package.json b/packages/enhanced-img/package.json index e0df5c9253b8..ee298abf3251 100644 --- a/packages/enhanced-img/package.json +++ b/packages/enhanced-img/package.json @@ -45,7 +45,7 @@ "devDependencies": { "@sveltejs/vite-plugin-svelte": "catalog:", "@types/estree": "^1.0.5", - "@types/node": "catalog:", + "@types/node": "^18.19.119", "rollup": "^4.27.4", "svelte": "^5.35.5", "typescript": "^5.6.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4b70f9856b78..f9709ee25d98 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,9 +12,6 @@ catalogs: '@sveltejs/vite-plugin-svelte': specifier: ^6.0.0-next.3 version: 6.0.0-next.3 - '@types/node': - specifier: ^18.19.119 - version: 18.19.119 cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -400,7 +397,7 @@ importers: specifier: ^1.0.5 version: 1.0.8 '@types/node': - specifier: 'catalog:' + specifier: ^18.19.119 version: 18.19.119 rollup: specifier: ^4.27.4 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c520b3835bcb..5552fdfb0ded 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -14,7 +14,6 @@ packages: catalog: '@playwright/test': '^1.51.1' '@sveltejs/vite-plugin-svelte': '^6.0.0-next.3' - '@types/node': '^18.19.119' 'cross-env': '^7.0.3' 'vitest': '^3.2.3' 'vite': '^6.3.5' From acf66e98e6f39dc283d13ef59a55e3e5980e3a30 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 7 Aug 2025 13:15:10 -0600 Subject: [PATCH 19/74] i do not understand why this fixed anything --- pnpm-lock.yaml | 977 +++++++++++++------------------------------------ 1 file changed, 245 insertions(+), 732 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f9709ee25d98..62e3e2b0ebe8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,7 +34,7 @@ importers: version: 1.51.1 '@sveltejs/eslint-config': specifier: ^8.2.0 - version: 8.2.0(@stylistic/eslint-plugin-js@2.1.0(eslint@9.29.0(jiti@2.4.2)))(eslint-config-prettier@9.1.0(eslint@9.29.0(jiti@2.4.2)))(eslint-plugin-n@17.16.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-svelte@3.9.3(eslint@9.29.0(jiti@2.4.2))(svelte@5.35.5)(ts-node@10.9.2(@types/node@20.19.9)(typescript@5.8.3)))(eslint@9.29.0(jiti@2.4.2))(typescript-eslint@8.39.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(typescript@5.8.3) + version: 8.2.0(@stylistic/eslint-plugin-js@2.1.0(eslint@9.29.0(jiti@2.4.2)))(eslint-config-prettier@9.1.0(eslint@9.29.0(jiti@2.4.2)))(eslint-plugin-n@17.16.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-svelte@3.9.3(eslint@9.29.0(jiti@2.4.2))(svelte@5.35.5)(ts-node@10.9.2(@types/node@18.19.119)(typescript@5.8.3)))(eslint@9.29.0(jiti@2.4.2))(typescript-eslint@8.39.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(typescript@5.8.3) '@svitejs/changesets-changelog-github-compact': specifier: ^1.2.0 version: 1.2.0 @@ -92,7 +92,7 @@ importers: version: 18.19.119 esbuild: specifier: ^0.25.4 - version: 0.25.5 + version: 0.25.6 typescript: specifier: ^5.3.3 version: 5.8.3 @@ -107,7 +107,7 @@ importers: version: link:../../../../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) server-side-dep: specifier: file:server-side-dep version: file:packages/adapter-cloudflare/test/apps/pages/server-side-dep @@ -116,7 +116,7 @@ importers: version: 5.35.5 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) wrangler: specifier: ^4.14.3 version: 4.14.4(@cloudflare/workers-types@4.20250508.0) @@ -128,7 +128,7 @@ importers: version: link:../../../../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -140,7 +140,7 @@ importers: version: 5.35.5 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) wrangler: specifier: ^4.14.3 version: 4.14.4(@cloudflare/workers-types@4.20250508.0) @@ -152,14 +152,14 @@ importers: version: 2.2.5 esbuild: specifier: ^0.25.4 - version: 0.25.5 + version: 0.25.6 set-cookie-parser: specifier: ^2.6.0 version: 2.6.0 devDependencies: '@netlify/edge-functions': specifier: ^2.15.1 - version: 2.17.0 + version: 2.15.1 '@netlify/functions': specifier: ^4.0.0 version: 4.1.4(rollup@4.44.0) @@ -201,16 +201,16 @@ importers: version: link:../../../../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) netlify-cli: specifier: ^23.0.0 - version: 23.1.1(@types/node@20.19.9)(picomatch@4.0.3) + version: 23.1.1(@types/node@18.19.119)(picomatch@4.0.3) svelte: specifier: ^5.23.1 version: 5.35.5 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/adapter-netlify/test/apps/edge: devDependencies: @@ -219,16 +219,16 @@ importers: version: link:../../../../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) netlify-cli: specifier: ^23.0.0 - version: 23.1.1(@types/node@20.19.9)(picomatch@4.0.3) + version: 23.1.1(@types/node@18.19.119)(picomatch@4.0.3) svelte: specifier: ^5.23.1 version: 5.35.5 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/adapter-node: dependencies: @@ -304,7 +304,7 @@ importers: version: link:../../../../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) sirv-cli: specifier: ^3.0.0 version: 3.0.0 @@ -313,7 +313,7 @@ importers: version: 5.35.5 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/adapter-static/test/apps/spa: devDependencies: @@ -325,7 +325,7 @@ importers: version: link:../../../../kit '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) sirv-cli: specifier: ^3.0.0 version: 3.0.0 @@ -334,7 +334,7 @@ importers: version: 5.35.5 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/adapter-vercel: dependencies: @@ -343,7 +343,7 @@ importers: version: 0.30.0(rollup@4.44.0) esbuild: specifier: ^0.25.4 - version: 0.25.5 + version: 0.25.6 devDependencies: '@sveltejs/kit': specifier: workspace:^ @@ -379,7 +379,7 @@ importers: version: 0.30.17 sharp: specifier: ^0.34.1 - version: 0.34.1 + version: 0.34.3 svelte-parse-markup: specifier: ^0.1.5 version: 0.1.5(svelte@5.35.5) @@ -507,7 +507,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -525,7 +525,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/basics: devDependencies: @@ -543,7 +543,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -561,7 +561,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/dev-only: devDependencies: @@ -570,7 +570,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -615,7 +615,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/embed: devDependencies: @@ -624,7 +624,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -639,7 +639,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/hash-based-routing: devDependencies: @@ -648,7 +648,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -663,7 +663,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/no-ssr: devDependencies: @@ -672,7 +672,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -687,7 +687,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/options: devDependencies: @@ -699,7 +699,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -714,7 +714,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/options-2: devDependencies: @@ -726,7 +726,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -741,7 +741,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/prerendered-app-error-pages: devDependencies: @@ -750,7 +750,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -765,7 +765,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/apps/writes: devDependencies: @@ -774,7 +774,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -789,13 +789,13 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors: devDependencies: vitest: specifier: 'catalog:' - version: 3.2.3(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/prerender-entry-generator-mismatch: devDependencies: @@ -807,7 +807,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -819,7 +819,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/prerenderable-incorrect-fragment: devDependencies: @@ -831,7 +831,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -843,7 +843,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/prerenderable-not-prerendered: devDependencies: @@ -855,7 +855,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -867,7 +867,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/private-dynamic-env: devDependencies: @@ -876,7 +876,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -888,7 +888,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/private-dynamic-env-dynamic-import: devDependencies: @@ -897,7 +897,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -909,7 +909,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/private-static-env: devDependencies: @@ -918,7 +918,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) cross-env: specifier: 'catalog:' version: 7.0.3 @@ -933,7 +933,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/private-static-env-dynamic-import: devDependencies: @@ -942,7 +942,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -954,7 +954,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/server-only-folder: devDependencies: @@ -963,7 +963,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -975,7 +975,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/server-only-folder-dynamic-import: devDependencies: @@ -984,7 +984,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -996,7 +996,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/server-only-module: devDependencies: @@ -1005,7 +1005,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -1017,7 +1017,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/server-only-module-dynamic-import: devDependencies: @@ -1026,7 +1026,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -1038,7 +1038,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/service-worker-dynamic-public-env: devDependencies: @@ -1047,7 +1047,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -1059,7 +1059,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/service-worker-private-env: devDependencies: @@ -1068,7 +1068,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -1080,7 +1080,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/build-errors/apps/syntax-error: devDependencies: @@ -1089,7 +1089,7 @@ importers: version: link:../../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -1101,7 +1101,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/prerendering/basics: devDependencies: @@ -1110,7 +1110,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -1122,10 +1122,10 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) vitest: specifier: 'catalog:' - version: 3.2.3(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/prerendering/options: devDependencies: @@ -1134,7 +1134,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -1146,10 +1146,10 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) vitest: specifier: 'catalog:' - version: 3.2.3(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/kit/test/prerendering/paths-base: devDependencies: @@ -1158,7 +1158,7 @@ importers: version: link:../../.. '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) svelte: specifier: ^5.35.5 version: 5.35.5 @@ -1170,10 +1170,10 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) vitest: specifier: 'catalog:' - version: 3.2.3(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages/package: dependencies: @@ -1258,7 +1258,7 @@ importers: version: link:../../packages/package '@sveltejs/vite-plugin-svelte': specifier: 'catalog:' - version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) + version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) prettier: specifier: ^3.3.2 version: 3.6.0 @@ -1279,7 +1279,7 @@ importers: version: 5.8.3 vite: specifier: 'catalog:' - version: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) + version: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) packages: @@ -1457,9 +1457,6 @@ packages: resolution: {integrity: sha512-Y6+WUMsTFWE5jb20IFP4YGa5IrGY/+a/FbOSjDF/wz9gepU2hwCYSXRHP/vPwBvwcY3SVMASt4yXxbXNXigmZQ==} engines: {node: '>=18'} - '@emnapi/runtime@1.4.3': - resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} - '@emnapi/runtime@1.4.5': resolution: {integrity: sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==} @@ -1945,8 +1942,8 @@ packages: resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.15.0': - resolution: {integrity: sha512-b7ePw78tEWWkpgZCDYkbqDOP8dmM6qe+AOC6iuJqlq1R/0ahMAeH3qynpnqKFGkMltrp44ohV4ubGyvLX28tzw==} + '@eslint/core@0.15.1': + resolution: {integrity: sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.3.1': @@ -1961,8 +1958,8 @@ packages: resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.3.2': - resolution: {integrity: sha512-4SaFZCNfJqvk/kenHpI8xvN42DMaoycy4PzKc5otHxRswww1kAt82OlBuwRVLofCACCTZEcla2Ydxv8scMXaTg==} + '@eslint/plugin-kit@0.3.4': + resolution: {integrity: sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@fastify/accept-negotiator@1.1.0': @@ -2042,12 +2039,6 @@ packages: cpu: [arm64] os: [darwin] - '@img/sharp-darwin-arm64@0.34.1': - resolution: {integrity: sha512-pn44xgBtgpEbZsu+lWf2KNb6OAf70X68k+yk69Ic2Xz11zHR/w24/U49XT7AeRwJ0Px+mhALhU5LPci1Aymk7A==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [darwin] - '@img/sharp-darwin-arm64@0.34.3': resolution: {integrity: sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -2060,12 +2051,6 @@ packages: cpu: [x64] os: [darwin] - '@img/sharp-darwin-x64@0.34.1': - resolution: {integrity: sha512-VfuYgG2r8BpYiOUN+BfYeFo69nP/MIwAtSJ7/Zpxc5QF3KS22z8Pvg3FkrSFJBPNQ7mmcUcYQFBmEQp7eu1F8Q==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [darwin] - '@img/sharp-darwin-x64@0.34.3': resolution: {integrity: sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -2077,11 +2062,6 @@ packages: cpu: [arm64] os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.1.0': - resolution: {integrity: sha512-HZ/JUmPwrJSoM4DIQPv/BfNh9yrOA8tlBbqbLz4JZ5uew2+o22Ik+tHQJcih7QJuSa0zo5coHTfD5J8inqj9DA==} - cpu: [arm64] - os: [darwin] - '@img/sharp-libvips-darwin-arm64@1.2.0': resolution: {integrity: sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==} cpu: [arm64] @@ -2092,11 +2072,6 @@ packages: cpu: [x64] os: [darwin] - '@img/sharp-libvips-darwin-x64@1.1.0': - resolution: {integrity: sha512-Xzc2ToEmHN+hfvsl9wja0RlnXEgpKNmftriQp6XzY/RaSfwD9th+MSh0WQKzUreLKKINb3afirxW7A0fz2YWuQ==} - cpu: [x64] - os: [darwin] - '@img/sharp-libvips-darwin-x64@1.2.0': resolution: {integrity: sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==} cpu: [x64] @@ -2107,11 +2082,6 @@ packages: cpu: [arm64] os: [linux] - '@img/sharp-libvips-linux-arm64@1.1.0': - resolution: {integrity: sha512-IVfGJa7gjChDET1dK9SekxFFdflarnUB8PwW8aGwEoF3oAsSDuNUTYS+SKDOyOJxQyDC1aPFMuRYLoDInyV9Ew==} - cpu: [arm64] - os: [linux] - '@img/sharp-libvips-linux-arm64@1.2.0': resolution: {integrity: sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==} cpu: [arm64] @@ -2122,21 +2092,11 @@ packages: cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-arm@1.1.0': - resolution: {integrity: sha512-s8BAd0lwUIvYCJyRdFqvsj+BJIpDBSxs6ivrOPm/R7piTs5UIwY5OjXrP2bqXC9/moGsyRa37eYWYCOGVXxVrA==} - cpu: [arm] - os: [linux] - '@img/sharp-libvips-linux-arm@1.2.0': resolution: {integrity: sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==} cpu: [arm] os: [linux] - '@img/sharp-libvips-linux-ppc64@1.1.0': - resolution: {integrity: sha512-tiXxFZFbhnkWE2LA8oQj7KYR+bWBkiV2nilRldT7bqoEZ4HiDOcePr9wVDAZPi/Id5fT1oY9iGnDq20cwUz8lQ==} - cpu: [ppc64] - os: [linux] - '@img/sharp-libvips-linux-ppc64@1.2.0': resolution: {integrity: sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==} cpu: [ppc64] @@ -2147,11 +2107,6 @@ packages: cpu: [s390x] os: [linux] - '@img/sharp-libvips-linux-s390x@1.1.0': - resolution: {integrity: sha512-xukSwvhguw7COyzvmjydRb3x/09+21HykyapcZchiCUkTThEQEOMtBj9UhkaBRLuBrgLFzQ2wbxdeCCJW/jgJA==} - cpu: [s390x] - os: [linux] - '@img/sharp-libvips-linux-s390x@1.2.0': resolution: {integrity: sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==} cpu: [s390x] @@ -2162,11 +2117,6 @@ packages: cpu: [x64] os: [linux] - '@img/sharp-libvips-linux-x64@1.1.0': - resolution: {integrity: sha512-yRj2+reB8iMg9W5sULM3S74jVS7zqSzHG3Ol/twnAAkAhnGQnpjj6e4ayUz7V+FpKypwgs82xbRdYtchTTUB+Q==} - cpu: [x64] - os: [linux] - '@img/sharp-libvips-linux-x64@1.2.0': resolution: {integrity: sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==} cpu: [x64] @@ -2177,11 +2127,6 @@ packages: cpu: [arm64] os: [linux] - '@img/sharp-libvips-linuxmusl-arm64@1.1.0': - resolution: {integrity: sha512-jYZdG+whg0MDK+q2COKbYidaqW/WTz0cc1E+tMAusiDygrM4ypmSCjOJPmFTvHHJ8j/6cAGyeDWZOsK06tP33w==} - cpu: [arm64] - os: [linux] - '@img/sharp-libvips-linuxmusl-arm64@1.2.0': resolution: {integrity: sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==} cpu: [arm64] @@ -2192,11 +2137,6 @@ packages: cpu: [x64] os: [linux] - '@img/sharp-libvips-linuxmusl-x64@1.1.0': - resolution: {integrity: sha512-wK7SBdwrAiycjXdkPnGCPLjYb9lD4l6Ze2gSdAGVZrEL05AOUJESWU2lhlC+Ffn5/G+VKuSm6zzbQSzFX/P65A==} - cpu: [x64] - os: [linux] - '@img/sharp-libvips-linuxmusl-x64@1.2.0': resolution: {integrity: sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==} cpu: [x64] @@ -2208,12 +2148,6 @@ packages: cpu: [arm64] os: [linux] - '@img/sharp-linux-arm64@0.34.1': - resolution: {integrity: sha512-kX2c+vbvaXC6vly1RDf/IWNXxrlxLNpBVWkdpRq5Ka7OOKj6nr66etKy2IENf6FtOgklkg9ZdGpEu9kwdlcwOQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - '@img/sharp-linux-arm64@0.34.3': resolution: {integrity: sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -2226,12 +2160,6 @@ packages: cpu: [arm] os: [linux] - '@img/sharp-linux-arm@0.34.1': - resolution: {integrity: sha512-anKiszvACti2sGy9CirTlNyk7BjjZPiML1jt2ZkTdcvpLU1YH6CXwRAZCA2UmRXnhiIftXQ7+Oh62Ji25W72jA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm] - os: [linux] - '@img/sharp-linux-arm@0.34.3': resolution: {integrity: sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -2250,12 +2178,6 @@ packages: cpu: [s390x] os: [linux] - '@img/sharp-linux-s390x@0.34.1': - resolution: {integrity: sha512-7s0KX2tI9mZI2buRipKIw2X1ufdTeaRgwmRabt5bi9chYfhur+/C1OXg3TKg/eag1W+6CCWLVmSauV1owmRPxA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [s390x] - os: [linux] - '@img/sharp-linux-s390x@0.34.3': resolution: {integrity: sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -2268,12 +2190,6 @@ packages: cpu: [x64] os: [linux] - '@img/sharp-linux-x64@0.34.1': - resolution: {integrity: sha512-wExv7SH9nmoBW3Wr2gvQopX1k8q2g5V5Iag8Zk6AVENsjwd+3adjwxtp3Dcu2QhOXr8W9NusBU6XcQUohBZ5MA==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - '@img/sharp-linux-x64@0.34.3': resolution: {integrity: sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -2286,12 +2202,6 @@ packages: cpu: [arm64] os: [linux] - '@img/sharp-linuxmusl-arm64@0.34.1': - resolution: {integrity: sha512-DfvyxzHxw4WGdPiTF0SOHnm11Xv4aQexvqhRDAoD00MzHekAj9a/jADXeXYCDFH/DzYruwHbXU7uz+H+nWmSOQ==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [arm64] - os: [linux] - '@img/sharp-linuxmusl-arm64@0.34.3': resolution: {integrity: sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -2304,12 +2214,6 @@ packages: cpu: [x64] os: [linux] - '@img/sharp-linuxmusl-x64@0.34.1': - resolution: {integrity: sha512-pax/kTR407vNb9qaSIiWVnQplPcGU8LRIJpDT5o8PdAx5aAA7AS3X9PS8Isw1/WfqgQorPotjrZL3Pqh6C5EBg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [linux] - '@img/sharp-linuxmusl-x64@0.34.3': resolution: {integrity: sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -2321,11 +2225,6 @@ packages: engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} cpu: [wasm32] - '@img/sharp-wasm32@0.34.1': - resolution: {integrity: sha512-YDybQnYrLQfEpzGOQe7OKcyLUCML4YOXl428gOOzBgN6Gw0rv8dpsJ7PqTHxBnXnwXr8S1mYFSLSa727tpz0xg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [wasm32] - '@img/sharp-wasm32@0.34.3': resolution: {integrity: sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -2343,12 +2242,6 @@ packages: cpu: [ia32] os: [win32] - '@img/sharp-win32-ia32@0.34.1': - resolution: {integrity: sha512-WKf/NAZITnonBf3U1LfdjoMgNO5JYRSlhovhRhMxXVdvWYveM4kM3L8m35onYIdh75cOMCo1BexgVQcCDzyoWw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [ia32] - os: [win32] - '@img/sharp-win32-ia32@0.34.3': resolution: {integrity: sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -2361,12 +2254,6 @@ packages: cpu: [x64] os: [win32] - '@img/sharp-win32-x64@0.34.1': - resolution: {integrity: sha512-hw1iIAHpNE8q3uMIRCgGOeDoz9KtFNarFLQclLxr/LK1VBkj8nby18RjFvr6aP7USRYAjTZW6yisnBWMX571Tw==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - cpu: [x64] - os: [win32] - '@img/sharp-win32-x64@0.34.3': resolution: {integrity: sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -2470,14 +2357,14 @@ packages: resolution: {integrity: sha512-5QPVts2j7RHMNVPVB7E28TC564TarS2JDTfMzKGzCrAY35bvOcfJ60Hhp8DOVjI13+BJgN37srUJP4OBDIXCfg==} engines: {node: ^18.14.0 || >=20} + '@netlify/dev-utils@3.2.1': + resolution: {integrity: sha512-a96wZheD3duD20aEJXBIui73GewRIcKwsXyzyFyerrsDffQjaWFuWxU9fnVSiunl6UVrvpBjWMJRGkCv4zf2KQ==} + engines: {node: ^18.14.0 || >=20} + '@netlify/dev-utils@4.1.1': resolution: {integrity: sha512-Y3kVGxynxi/Lz42bi20A+PQ0vh25zVjbGnQWZQUTwLzQozEIeokCgUWskPvlhs6btheLZyzUjqGuhUCymOoD1g==} engines: {node: ^18.14.0 || >=20} - '@netlify/edge-bundler@14.4.0': - resolution: {integrity: sha512-/G4y1dr1KR2Jsji5uSruAsMQvoxK0cfAkvC+RfjSERh9Ra/So/ukMgb4ucybso4hrgfuXZVdTWHSyH6pAxEp/w==} - engines: {node: '>=18.14.0'} - '@netlify/edge-bundler@14.4.1': resolution: {integrity: sha512-C89Tkj5PGkA2CpqwqiZ91nBkufZjB6ZUdOTVcq3D+jf38LA3KQi8NceCsgwCeuzOzo3Dn0Te9GYhJRjqeN//jQ==} engines: {node: '>=18.14.0'} @@ -2485,8 +2372,8 @@ packages: '@netlify/edge-functions-bootstrap@2.14.0': resolution: {integrity: sha512-Fs1cQ+XKfKr2OxrAvmX+S46CJmrysxBdCUCTk/wwcCZikrDvsYUFG7FTquUl4JfAf9taYYyW/tPv35gKOKS8BQ==} - '@netlify/edge-functions@2.17.0': - resolution: {integrity: sha512-dSrRFBON77gMjt5TYFWnB3BPbfBiRFL/bWqxj8cXVNxIv0qCd4l2lV3C4+Ipg9i0hPEG8z9bHs6HuJi3ZXfUyw==} + '@netlify/edge-functions@2.15.1': + resolution: {integrity: sha512-iu9FYYlD6crNfX8GqS5vywfkfdWWpMqnqzXrGh67iB7b+KdTPpPXsRNSRxfvL/o3GO9HJc/zmTMwXhPXDn/2fA==} engines: {node: '>=18.0.0'} '@netlify/functions-utils@6.2.1': @@ -2615,10 +2502,6 @@ packages: resolution: {integrity: sha512-bNlN/hpND8xFQzpjyKxm6vJayD+bPBlOvs4lWihE7WULrphuH1UuFsoVE5386bNNGH8Rs1IH01AFsl7ALQgOlQ==} engines: {node: '>=18.0.0'} - '@netlify/types@2.0.2': - resolution: {integrity: sha512-6899BAqehToSAd3hoevqGaIkG0M9epPMLTi6byynNVIzqv2x+b9OtRXqK67G/gCX7XkrtLQ9Xm3QNJmaFNrSXA==} - engines: {node: ^18.14.0 || >=20} - '@netlify/zip-it-and-ship-it@12.1.4': resolution: {integrity: sha512-/wM1c0iyym/7SlowbgqTuu/+tJS8CDDs4vLhSizKntFl3VOeDVX0kr9qriH9wA2hYstwGSuHsEgEAnKdMcDBOg==} engines: {node: '>=18.14.0'} @@ -2645,8 +2528,8 @@ packages: resolution: {integrity: sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw==} engines: {node: '>= 18'} - '@octokit/core@6.1.6': - resolution: {integrity: sha512-kIU8SLQkYWGp3pVKiYzA5OSaNF5EE03P/R8zEmmrG6XwOg5oBjXyQVVIauQ0dgau4zYhpZEhJrvIYt6oM+zZZA==} + '@octokit/core@6.1.5': + resolution: {integrity: sha512-vvmsN0r7rguA+FySiCsbaTTobSftpIDIpPW81trAmsv9TGxg3YCujAxRYp/Uy8xmDgYCzzgulG62H7KYUFmeIg==} engines: {node: '>= 18'} '@octokit/endpoint@10.1.4': @@ -3266,9 +3149,6 @@ packages: '@types/node@18.19.119': resolution: {integrity: sha512-d0F6m9itIPaKnrvEMlzE48UjwZaAnFW7Jwibacw9MNdqadjKNpUm9tfJYDwmShJmgqcoqYUX3EMKO1+RWiuuNg==} - '@types/node@20.19.9': - resolution: {integrity: sha512-cuVNgarYWZqxRJDQHEB58GEONhOK79QVR/qYx4S7kcUObQvUwvFnYxJuuHUKm2aieN9X3yZB4LZsuYNU1Qphsw==} - '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -3305,12 +3185,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.37.0': - resolution: {integrity: sha512-BIUXYsbkl5A1aJDdYJCBAo8rCEbAvdquQ8AnLb6z5Lp1u3x5PNgSSx9A/zqYc++Xnr/0DVpls8iQ2cJs/izTXA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/project-service@8.39.0': resolution: {integrity: sha512-CTzJqaSq30V/Z2Og9jogzZt8lJRR5TKlAdXmWgdu4hgcC9Kww5flQ+xFvMxIBWVNdxJO7OifgdOK4PokMIWPew==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3321,12 +3195,6 @@ packages: resolution: {integrity: sha512-8QOzff9UKxOh6npZQ/4FQu4mjdOCGSdO3p44ww0hk8Vu+IGbg0tB/H1LcTARRDzGCC8pDGbh2rissBuuoPgH8A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.37.0': - resolution: {integrity: sha512-1/YHvAVTimMM9mmlPvTec9NP4bobA1RkDbMydxG8omqwJJLEW/Iy2C4adsAESIXU3WGLXFHSZUU+C9EoFWl4Zg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/tsconfig-utils@8.39.0': resolution: {integrity: sha512-Fd3/QjmFV2sKmvv3Mrj8r6N8CryYiCS8Wdb/6/rgOXAWGcFuc+VkQuG28uk/4kVNVZBQuuDHEDUpo/pQ32zsIQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3340,20 +3208,10 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.37.0': - resolution: {integrity: sha512-ax0nv7PUF9NOVPs+lmQ7yIE7IQmAf8LGcXbMvHX5Gm+YJUYNAl340XkGnrimxZ0elXyoQJuN5sbg6C4evKA4SQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.39.0': resolution: {integrity: sha512-ArDdaOllnCj3yn/lzKn9s0pBQYmmyme/v1HbGIGB0GB/knFI3fWMHloC+oYTJW46tVbYnGKTMDK4ah1sC2v0Kg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.37.0': - resolution: {integrity: sha512-zuWDMDuzMRbQOM+bHyU4/slw27bAUEcKSKKs3hcv2aNnc/tvE/h7w60dwVw8vnal2Pub6RT1T7BI8tFZ1fE+yg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/typescript-estree@8.39.0': resolution: {integrity: sha512-ndWdiflRMvfIgQRpckQQLiB5qAKQ7w++V4LlCHwp62eym1HLB/kw7D9f2e8ytONls/jt89TEasgvb+VwnRprsw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3367,10 +3225,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.37.0': - resolution: {integrity: sha512-YzfhzcTnZVPiLfP/oeKtDp2evwvHLMe0LOy7oe+hb9KKIumLNohYS9Hgp1ifwpu42YWxhZE8yieggz6JpqO/1w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.39.0': resolution: {integrity: sha512-ldgiJ+VAhQCfIjeOgu8Kj5nSxds0ktPOSO9p4+0VDH2R2pLvQraaM5Oen2d7NxzMCm+Sn/vJT+mv2H5u6b/3fA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3506,10 +3360,6 @@ packages: resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} engines: {node: '>=0.4.0'} - acorn-walk@8.3.4: - resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} - engines: {node: '>=0.4.0'} - acorn@8.14.0: resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} engines: {node: '>=0.4.0'} @@ -3946,10 +3796,6 @@ packages: resolution: {integrity: sha512-yk7/5PN5im4qwz0WFZW3PXnzHgPu9mX29Y8uZ3aefe2lBPC1FYttWZRcaW9fKkT0pBCJyuQ2HfbmPVaODi9jcQ==} engines: {node: '>=18'} - consola@3.2.3: - resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} - engines: {node: ^14.18.0 || >=16.10.0} - consola@3.4.2: resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} @@ -4027,8 +3873,8 @@ packages: crossws@0.3.5: resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} - css-select@5.2.2: - resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} css-tree@2.2.1: resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} @@ -4038,8 +3884,8 @@ packages: resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - css-what@6.2.2: - resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} engines: {node: '>= 6'} cssesc@3.0.0: @@ -4238,10 +4084,6 @@ packages: resolution: {integrity: sha512-1gxPBJpI/pcjQhKgIU91II6Wkay+dLcN3M6rf2uwP8hRur3HtQXjVrdAK3sjC0piaEuxzMwjXChcETiJl47lAQ==} engines: {node: '>=18'} - dotenv@16.4.5: - resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} - engines: {node: '>=12'} - dotenv@16.6.1: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} @@ -4692,8 +4534,8 @@ packages: folder-walker@3.2.0: resolution: {integrity: sha512-VjAQdSLsl6AkpZNyrQJfO7BXLo4chnStqb055bumZMbRUPpVuPN3a4ktsnRCmrFZjtMlYLkyXiR5rAs4WOpC4Q==} - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -4765,12 +4607,8 @@ packages: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} - get-package-name@2.2.0: - resolution: {integrity: sha512-LmCKVxioe63Fy6KDAQ/mmCSOSSRUE/x4zdrMD+7dU8quF3bGpzvP8mOmq4Dgce3nzU9AgkVDotucNOOg7c27BQ==} - engines: {node: '>= 12.0.0'} - - get-port-please@3.2.0: - resolution: {integrity: sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==} + get-port-please@3.1.2: + resolution: {integrity: sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ==} get-port@5.1.1: resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} @@ -4878,8 +4716,8 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - h3@1.15.4: - resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} + h3@1.15.3: + resolution: {integrity: sha512-z6GknHqyX0h9aQaTx22VZDf6QyZn+0Nh+Ym8O/u0SGSkyF5cuTJYKlc8MkzW3Nzf9LE1ivcpmYC3FUGpywhuUQ==} has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} @@ -5279,8 +5117,8 @@ packages: kuler@2.0.0: resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} - ky@1.8.2: - resolution: {integrity: sha512-XybQJ3d4Ea1kI27DoelE5ZCT3bSJlibYTtQuMsyzKox3TMyayw1asgQdl54WroAm+fIA3ZCr8zXW2RpR7qWVpA==} + ky@1.8.1: + resolution: {integrity: sha512-7Bp3TpsE+L+TARSnnDpk3xg8Idi8RwSLdj6CMbNWoOARIrGrbuLGusV0dYwbZOm4bB3jHNxSw8Wk/ByDqJEnDw==} engines: {node: '>=18'} lambda-local@2.2.0: @@ -5669,8 +5507,8 @@ packages: mute-stream@0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} - nan@2.23.0: - resolution: {integrity: sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==} + nan@2.22.2: + resolution: {integrity: sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==} nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} @@ -5706,8 +5544,8 @@ packages: engines: {node: '>=10.5.0'} deprecated: Use your platform's native DOMException instead - node-fetch-native@1.6.7: - resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + node-fetch-native@1.6.6: + resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==} node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} @@ -5730,8 +5568,8 @@ packages: resolution: {integrity: sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==} hasBin: true - node-mock-http@1.0.2: - resolution: {integrity: sha512-zWaamgDUdo9SSLw47we78+zYw/bDr5gH8pH7oRRs8V3KmBtu8GLgGIbV2p/gRPd3LWpEOpjQj7X1FOU3VFMJ8g==} + node-mock-http@1.0.0: + resolution: {integrity: sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ==} node-source-walk@7.0.1: resolution: {integrity: sha512-3VW/8JpPqPvnJvseXowjZcirPisssnBuDikk6JIZ8jQzF7KJQX52iPFX4RYYxLycYH7IbMRSPUOga/esVjy5Yg==} @@ -6267,10 +6105,6 @@ packages: readdir-glob@1.1.3: resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} - readdirp@4.0.1: - resolution: {integrity: sha512-GkMg9uOTpIWWKbSsgwb5fA4EavTR+SG/PMPoAY8hkhHfEEY0/vqljY+XHqtDf2cr2IJtoNRDbrrEpZUiZCkYRw==} - engines: {node: '>= 14.16.0'} - readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} @@ -6461,10 +6295,6 @@ packages: resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - sharp@0.34.1: - resolution: {integrity: sha512-1j0w61+eVxu7DawFJtnfYcvSv6qPFvfTaqzTQ2BLknVhHTwGS8sc63ZBF4rzkWMBVKybo4S5OBtDdZahh2A1xg==} - engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - sharp@0.34.3: resolution: {integrity: sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -6677,8 +6507,8 @@ packages: stubborn-fs@1.2.5: resolution: {integrity: sha512-H2N9c26eXjzL/S/K+i/RHHcFanE74dptvvjM8iwzwbVcWY/zjBbgRqF3K0DY4+OD+uTTASTBvDoxPDaPN02D7g==} - supports-color@10.1.0: - resolution: {integrity: sha512-GBuewsPrhJPftT+fqDa9oI/zc5HNsG9nREqwzoSFDOIqf0NggOZbHQj2TE1P1CDJK8ZogFnlZY9hWoUiur7I/A==} + supports-color@10.0.0: + resolution: {integrity: sha512-HRVVSbCCMbj7/kdWF9Q+bbckjBHLtHMEoJWlkmYzzdwhYMkjkOwubLM6t7NbWKjgKamGDrWL1++KrjUO1t9oAQ==} engines: {node: '>=18'} supports-color@7.2.0: @@ -6701,8 +6531,8 @@ packages: svelte: ^4.0.0 || ^5.0.0-next.0 typescript: '>=5.0.0' - svelte-eslint-parser@1.2.0: - resolution: {integrity: sha512-mbPtajIeuiyU80BEyGvwAktBeTX7KCr5/0l+uRGLq1dafwRNrjfM5kHGJScEBlPG3ipu6dJqfW/k0/fujvIEVw==} + svelte-eslint-parser@1.3.1: + resolution: {integrity: sha512-0Iztj5vcOVOVkhy1pbo5uA9r+d3yaVoE5XPc9eABIWDOSJZ2mOsZ4D+t45rphWCOr0uMw3jtSG2fh2e7GvKnPg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 @@ -6968,9 +6798,6 @@ packages: undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - undici-types@6.21.0: - resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici@5.29.0: resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} engines: {node: '>=14.0'} @@ -7389,8 +7216,8 @@ packages: zod@3.25.56: resolution: {integrity: sha512-rd6eEF3BTNvQnR2e2wwolfTmUTnp70aUTqr0oaGbHifzC3BKJsoV+Gat8vxUMR1hwOKBs6El+qWehrHbCpW6SQ==} - zod@4.0.15: - resolution: {integrity: sha512-2IVHb9h4Mt6+UXkyMs0XbfICUh1eUrlJJAOupBHUhLRnKkruawyDddYRCs0Eizt900ntIMk9/4RksYl+FgSpcQ==} + zod@4.0.14: + resolution: {integrity: sha512-nGFJTnJN6cM2v9kXL+SOBq3AtjQby3Mv5ySGFof5UGRHrRioSJ5iG680cYNjE/yWk671nROcpPj4hAS8nyLhSw==} snapshots: @@ -7413,7 +7240,7 @@ snapshots: '@babel/parser@7.27.5': dependencies: - '@babel/types': 7.27.6 + '@babel/types': 7.28.1 '@babel/runtime@7.26.10': dependencies: @@ -7652,11 +7479,6 @@ snapshots: gonzales-pe: 4.3.0 node-source-walk: 7.0.1 - '@emnapi/runtime@1.4.3': - dependencies: - tslib: 2.8.1 - optional: true - '@emnapi/runtime@1.4.5': dependencies: tslib: 2.8.1 @@ -7905,7 +7727,7 @@ snapshots: '@eslint/config-array@0.20.1': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -7916,14 +7738,14 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/core@0.15.0': + '@eslint/core@0.15.1': dependencies: '@types/json-schema': 7.0.15 '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 @@ -7938,9 +7760,9 @@ snapshots: '@eslint/object-schema@2.1.6': {} - '@eslint/plugin-kit@0.3.2': + '@eslint/plugin-kit@0.3.4': dependencies: - '@eslint/core': 0.15.0 + '@eslint/core': 0.15.1 levn: 0.4.1 '@fastify/accept-negotiator@1.1.0': {} @@ -8020,11 +7842,6 @@ snapshots: '@img/sharp-libvips-darwin-arm64': 1.0.4 optional: true - '@img/sharp-darwin-arm64@0.34.1': - optionalDependencies: - '@img/sharp-libvips-darwin-arm64': 1.1.0 - optional: true - '@img/sharp-darwin-arm64@0.34.3': optionalDependencies: '@img/sharp-libvips-darwin-arm64': 1.2.0 @@ -8035,11 +7852,6 @@ snapshots: '@img/sharp-libvips-darwin-x64': 1.0.4 optional: true - '@img/sharp-darwin-x64@0.34.1': - optionalDependencies: - '@img/sharp-libvips-darwin-x64': 1.1.0 - optional: true - '@img/sharp-darwin-x64@0.34.3': optionalDependencies: '@img/sharp-libvips-darwin-x64': 1.2.0 @@ -8048,78 +7860,51 @@ snapshots: '@img/sharp-libvips-darwin-arm64@1.0.4': optional: true - '@img/sharp-libvips-darwin-arm64@1.1.0': - optional: true - '@img/sharp-libvips-darwin-arm64@1.2.0': optional: true '@img/sharp-libvips-darwin-x64@1.0.4': optional: true - '@img/sharp-libvips-darwin-x64@1.1.0': - optional: true - '@img/sharp-libvips-darwin-x64@1.2.0': optional: true '@img/sharp-libvips-linux-arm64@1.0.4': optional: true - '@img/sharp-libvips-linux-arm64@1.1.0': - optional: true - '@img/sharp-libvips-linux-arm64@1.2.0': optional: true '@img/sharp-libvips-linux-arm@1.0.5': optional: true - '@img/sharp-libvips-linux-arm@1.1.0': - optional: true - '@img/sharp-libvips-linux-arm@1.2.0': optional: true - '@img/sharp-libvips-linux-ppc64@1.1.0': - optional: true - '@img/sharp-libvips-linux-ppc64@1.2.0': optional: true '@img/sharp-libvips-linux-s390x@1.0.4': optional: true - '@img/sharp-libvips-linux-s390x@1.1.0': - optional: true - '@img/sharp-libvips-linux-s390x@1.2.0': optional: true '@img/sharp-libvips-linux-x64@1.0.4': optional: true - '@img/sharp-libvips-linux-x64@1.1.0': - optional: true - '@img/sharp-libvips-linux-x64@1.2.0': optional: true '@img/sharp-libvips-linuxmusl-arm64@1.0.4': optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.1.0': - optional: true - '@img/sharp-libvips-linuxmusl-arm64@1.2.0': optional: true '@img/sharp-libvips-linuxmusl-x64@1.0.4': optional: true - '@img/sharp-libvips-linuxmusl-x64@1.1.0': - optional: true - '@img/sharp-libvips-linuxmusl-x64@1.2.0': optional: true @@ -8128,11 +7913,6 @@ snapshots: '@img/sharp-libvips-linux-arm64': 1.0.4 optional: true - '@img/sharp-linux-arm64@0.34.1': - optionalDependencies: - '@img/sharp-libvips-linux-arm64': 1.1.0 - optional: true - '@img/sharp-linux-arm64@0.34.3': optionalDependencies: '@img/sharp-libvips-linux-arm64': 1.2.0 @@ -8143,11 +7923,6 @@ snapshots: '@img/sharp-libvips-linux-arm': 1.0.5 optional: true - '@img/sharp-linux-arm@0.34.1': - optionalDependencies: - '@img/sharp-libvips-linux-arm': 1.1.0 - optional: true - '@img/sharp-linux-arm@0.34.3': optionalDependencies: '@img/sharp-libvips-linux-arm': 1.2.0 @@ -8163,11 +7938,6 @@ snapshots: '@img/sharp-libvips-linux-s390x': 1.0.4 optional: true - '@img/sharp-linux-s390x@0.34.1': - optionalDependencies: - '@img/sharp-libvips-linux-s390x': 1.1.0 - optional: true - '@img/sharp-linux-s390x@0.34.3': optionalDependencies: '@img/sharp-libvips-linux-s390x': 1.2.0 @@ -8178,11 +7948,6 @@ snapshots: '@img/sharp-libvips-linux-x64': 1.0.4 optional: true - '@img/sharp-linux-x64@0.34.1': - optionalDependencies: - '@img/sharp-libvips-linux-x64': 1.1.0 - optional: true - '@img/sharp-linux-x64@0.34.3': optionalDependencies: '@img/sharp-libvips-linux-x64': 1.2.0 @@ -8193,11 +7958,6 @@ snapshots: '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 optional: true - '@img/sharp-linuxmusl-arm64@0.34.1': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 - optional: true - '@img/sharp-linuxmusl-arm64@0.34.3': optionalDependencies: '@img/sharp-libvips-linuxmusl-arm64': 1.2.0 @@ -8208,11 +7968,6 @@ snapshots: '@img/sharp-libvips-linuxmusl-x64': 1.0.4 optional: true - '@img/sharp-linuxmusl-x64@0.34.1': - optionalDependencies: - '@img/sharp-libvips-linuxmusl-x64': 1.1.0 - optional: true - '@img/sharp-linuxmusl-x64@0.34.3': optionalDependencies: '@img/sharp-libvips-linuxmusl-x64': 1.2.0 @@ -8220,12 +7975,7 @@ snapshots: '@img/sharp-wasm32@0.33.5': dependencies: - '@emnapi/runtime': 1.4.3 - optional: true - - '@img/sharp-wasm32@0.34.1': - dependencies: - '@emnapi/runtime': 1.4.3 + '@emnapi/runtime': 1.4.5 optional: true '@img/sharp-wasm32@0.34.3': @@ -8239,18 +7989,12 @@ snapshots: '@img/sharp-win32-ia32@0.33.5': optional: true - '@img/sharp-win32-ia32@0.34.1': - optional: true - '@img/sharp-win32-ia32@0.34.3': optional: true '@img/sharp-win32-x64@0.33.5': optional: true - '@img/sharp-win32-x64@0.34.1': - optional: true - '@img/sharp-win32-x64@0.34.3': optional: true @@ -8316,11 +8060,11 @@ snapshots: globby: 11.1.0 read-yaml-file: 1.1.0 - '@mapbox/node-pre-gyp@2.0.0(supports-color@10.1.0)': + '@mapbox/node-pre-gyp@2.0.0(supports-color@10.0.0)': dependencies: - consola: 3.2.3 + consola: 3.4.2 detect-libc: 2.0.4 - https-proxy-agent: 7.0.6(supports-color@10.1.0) + https-proxy-agent: 7.0.6(supports-color@10.0.0) node-fetch: 2.7.0 nopt: 8.0.0 semver: 7.7.2 @@ -8362,19 +8106,19 @@ snapshots: yaml: 2.8.0 yargs: 17.7.2 - '@netlify/build@35.0.3(@opentelemetry/api@1.8.0)(@types/node@20.19.9)(picomatch@4.0.3)': + '@netlify/build@35.0.3(@opentelemetry/api@1.8.0)(@types/node@18.19.119)(picomatch@4.0.3)': dependencies: '@bugsnag/js': 8.4.0 '@netlify/blobs': 10.0.8 '@netlify/cache-utils': 6.0.3 '@netlify/config': 24.0.1 '@netlify/edge-bundler': 14.4.1 - '@netlify/functions-utils': 6.2.1(supports-color@10.1.0) + '@netlify/functions-utils': 6.2.1(supports-color@10.0.0) '@netlify/git-utils': 6.0.2 '@netlify/opentelemetry-utils': 2.0.1(@opentelemetry/api@1.8.0) '@netlify/plugins-list': 6.80.0 '@netlify/run-utils': 6.0.2 - '@netlify/zip-it-and-ship-it': 14.1.1(supports-color@10.1.0) + '@netlify/zip-it-and-ship-it': 14.1.1(supports-color@10.0.0) '@opentelemetry/api': 1.8.0 '@sindresorhus/slugify': 2.2.1 ansi-escapes: 7.0.0 @@ -8408,9 +8152,9 @@ snapshots: safe-json-stringify: 1.2.0 semver: 7.7.2 string-width: 7.2.0 - supports-color: 10.1.0 + supports-color: 10.0.0 terminal-link: 4.0.0 - ts-node: 10.9.2(@types/node@20.19.9)(typescript@5.8.3) + ts-node: 10.9.2(@types/node@18.19.119)(typescript@5.8.3) typescript: 5.8.3 uuid: 11.1.0 yaml: 2.8.0 @@ -8460,7 +8204,7 @@ snapshots: validate-npm-package-name: 5.0.1 yaml: 2.8.0 yargs: 17.7.2 - zod: 4.0.15 + zod: 4.0.14 '@netlify/dev-utils@3.2.0': dependencies: @@ -8478,48 +8222,40 @@ snapshots: uuid: 11.1.0 write-file-atomic: 5.0.1 - '@netlify/dev-utils@4.1.1': + '@netlify/dev-utils@3.2.1': dependencies: '@whatwg-node/server': 0.10.10 ansis: 4.1.0 chokidar: 4.0.3 decache: 4.6.2 dot-prop: 9.0.0 - empathic: 2.0.0 env-paths: 3.0.0 + find-up: 7.0.0 image-size: 2.0.2 js-image-generator: 1.0.4 lodash.debounce: 4.0.8 parse-gitignore: 2.0.0 semver: 7.7.2 - tmp-promise: 3.0.3 uuid: 11.1.0 write-file-atomic: 5.0.1 - '@netlify/edge-bundler@14.4.0': + '@netlify/dev-utils@4.1.1': dependencies: - '@import-maps/resolve': 2.0.0 - ajv: 8.17.1 - ajv-errors: 3.0.0(ajv@8.17.1) - better-ajv-errors: 1.2.0(ajv@8.17.1) - common-path-prefix: 3.0.0 + '@whatwg-node/server': 0.10.10 + ansis: 4.1.0 + chokidar: 4.0.3 + decache: 4.6.2 + dot-prop: 9.0.0 + empathic: 2.0.0 env-paths: 3.0.0 - esbuild: 0.25.6 - execa: 8.0.1 - find-up: 7.0.0 - get-package-name: 2.2.0 - get-port: 7.1.0 - is-path-inside: 4.0.0 - node-stream-zip: 1.15.0 - p-retry: 6.2.1 - p-wait-for: 5.0.2 - parse-imports: 2.2.1 - path-key: 4.0.0 + image-size: 2.0.2 + js-image-generator: 1.0.4 + lodash.debounce: 4.0.8 + parse-gitignore: 2.0.0 semver: 7.7.2 - tar: 7.4.3 tmp-promise: 3.0.3 - urlpattern-polyfill: 8.0.2 uuid: 11.1.0 + write-file-atomic: 5.0.1 '@netlify/edge-bundler@14.4.1': dependencies: @@ -8546,18 +8282,17 @@ snapshots: '@netlify/edge-functions-bootstrap@2.14.0': {} - '@netlify/edge-functions@2.17.0': + '@netlify/edge-functions@2.15.1': dependencies: - '@netlify/dev-utils': 4.1.1 - '@netlify/edge-bundler': 14.4.0 + '@netlify/dev-utils': 3.2.1 + '@netlify/edge-bundler': 14.4.1 '@netlify/edge-functions-bootstrap': 2.14.0 '@netlify/runtime-utils': 2.1.0 - '@netlify/types': 2.0.2 get-port: 7.1.0 - '@netlify/functions-utils@6.2.1(supports-color@10.1.0)': + '@netlify/functions-utils@6.2.1(supports-color@10.0.0)': dependencies: - '@netlify/zip-it-and-ship-it': 14.1.1(supports-color@10.1.0) + '@netlify/zip-it-and-ship-it': 14.1.1(supports-color@10.0.0) cpy: 11.1.0 path-exists: 5.0.0 transitivePeerDependencies: @@ -8677,14 +8412,12 @@ snapshots: '@netlify/serverless-functions-api@2.1.3': {} - '@netlify/types@2.0.2': {} - '@netlify/zip-it-and-ship-it@12.1.4(rollup@4.44.0)': dependencies: '@babel/parser': 7.27.5 '@babel/types': 7.27.6 '@netlify/binary-info': 1.0.0 - '@netlify/serverless-functions-api': 2.1.1 + '@netlify/serverless-functions-api': 2.1.3 '@vercel/nft': 0.29.4(rollup@4.44.0) archiver: 7.0.1 common-path-prefix: 3.0.0 @@ -8704,7 +8437,7 @@ snapshots: normalize-path: 3.0.0 p-map: 7.0.3 path-exists: 5.0.0 - precinct: 12.2.0(supports-color@10.1.0) + precinct: 12.2.0(supports-color@10.0.0) require-package-name: 2.0.1 resolve: 2.0.0-next.5 semver: 7.7.2 @@ -8743,7 +8476,7 @@ snapshots: normalize-path: 3.0.0 p-map: 7.0.3 path-exists: 5.0.0 - precinct: 12.2.0(supports-color@10.1.0) + precinct: 12.2.0(supports-color@10.0.0) require-package-name: 2.0.1 resolve: 2.0.0-next.5 semver: 7.7.2 @@ -8758,13 +8491,13 @@ snapshots: - rollup - supports-color - '@netlify/zip-it-and-ship-it@14.1.1(supports-color@10.1.0)': + '@netlify/zip-it-and-ship-it@14.1.1(supports-color@10.0.0)': dependencies: '@babel/parser': 7.27.5 '@babel/types': 7.28.1 '@netlify/binary-info': 1.0.0 '@netlify/serverless-functions-api': 2.1.3 - '@vercel/nft': 0.30.0(supports-color@10.1.0) + '@vercel/nft': 0.30.0(supports-color@10.0.0) archiver: 7.0.1 common-path-prefix: 3.0.0 copy-file: 11.0.0 @@ -8782,7 +8515,7 @@ snapshots: normalize-path: 3.0.0 p-map: 7.0.3 path-exists: 5.0.0 - precinct: 12.2.0(supports-color@10.1.0) + precinct: 12.2.0(supports-color@10.0.0) require-package-name: 2.0.1 resolve: 2.0.0-next.5 semver: 7.7.2 @@ -8811,7 +8544,7 @@ snapshots: '@octokit/auth-token@5.1.2': {} - '@octokit/core@6.1.6': + '@octokit/core@6.1.5': dependencies: '@octokit/auth-token': 5.1.2 '@octokit/graphql': 8.2.2 @@ -8836,18 +8569,18 @@ snapshots: '@octokit/openapi-types@25.1.0': {} - '@octokit/plugin-paginate-rest@11.6.0(@octokit/core@6.1.6)': + '@octokit/plugin-paginate-rest@11.6.0(@octokit/core@6.1.5)': dependencies: - '@octokit/core': 6.1.6 + '@octokit/core': 6.1.5 '@octokit/types': 13.10.0 - '@octokit/plugin-request-log@5.3.1(@octokit/core@6.1.6)': + '@octokit/plugin-request-log@5.3.1(@octokit/core@6.1.5)': dependencies: - '@octokit/core': 6.1.6 + '@octokit/core': 6.1.5 - '@octokit/plugin-rest-endpoint-methods@13.5.0(@octokit/core@6.1.6)': + '@octokit/plugin-rest-endpoint-methods@13.5.0(@octokit/core@6.1.5)': dependencies: - '@octokit/core': 6.1.6 + '@octokit/core': 6.1.5 '@octokit/types': 13.10.0 '@octokit/request-error@6.1.8': @@ -8864,10 +8597,10 @@ snapshots: '@octokit/rest@21.1.1': dependencies: - '@octokit/core': 6.1.6 - '@octokit/plugin-paginate-rest': 11.6.0(@octokit/core@6.1.6) - '@octokit/plugin-request-log': 5.3.1(@octokit/core@6.1.6) - '@octokit/plugin-rest-endpoint-methods': 13.5.0(@octokit/core@6.1.6) + '@octokit/core': 6.1.5 + '@octokit/plugin-paginate-rest': 11.6.0(@octokit/core@6.1.5) + '@octokit/plugin-request-log': 5.3.1(@octokit/core@6.1.5) + '@octokit/plugin-rest-endpoint-methods': 13.5.0(@octokit/core@6.1.5) '@octokit/types@13.10.0': dependencies: @@ -9192,7 +8925,7 @@ snapshots: '@pnpm/tabtab@0.5.4': dependencies: - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) enquirer: 2.4.1 minimist: 1.2.8 untildify: 4.0.0 @@ -9351,13 +9084,13 @@ snapshots: dependencies: acorn: 8.15.0 - '@sveltejs/eslint-config@8.2.0(@stylistic/eslint-plugin-js@2.1.0(eslint@9.29.0(jiti@2.4.2)))(eslint-config-prettier@9.1.0(eslint@9.29.0(jiti@2.4.2)))(eslint-plugin-n@17.16.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-svelte@3.9.3(eslint@9.29.0(jiti@2.4.2))(svelte@5.35.5)(ts-node@10.9.2(@types/node@20.19.9)(typescript@5.8.3)))(eslint@9.29.0(jiti@2.4.2))(typescript-eslint@8.39.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(typescript@5.8.3)': + '@sveltejs/eslint-config@8.2.0(@stylistic/eslint-plugin-js@2.1.0(eslint@9.29.0(jiti@2.4.2)))(eslint-config-prettier@9.1.0(eslint@9.29.0(jiti@2.4.2)))(eslint-plugin-n@17.16.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint-plugin-svelte@3.9.3(eslint@9.29.0(jiti@2.4.2))(svelte@5.35.5)(ts-node@10.9.2(@types/node@18.19.119)(typescript@5.8.3)))(eslint@9.29.0(jiti@2.4.2))(typescript-eslint@8.39.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(typescript@5.8.3)': dependencies: '@stylistic/eslint-plugin-js': 2.1.0(eslint@9.29.0(jiti@2.4.2)) eslint: 9.29.0(jiti@2.4.2) eslint-config-prettier: 9.1.0(eslint@9.29.0(jiti@2.4.2)) eslint-plugin-n: 17.16.1(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) - eslint-plugin-svelte: 3.9.3(eslint@9.29.0(jiti@2.4.2))(svelte@5.35.5)(ts-node@10.9.2(@types/node@20.19.9)(typescript@5.8.3)) + eslint-plugin-svelte: 3.9.3(eslint@9.29.0(jiti@2.4.2))(svelte@5.35.5)(ts-node@10.9.2(@types/node@18.19.119)(typescript@5.8.3)) globals: 15.15.0 typescript: 5.8.3 typescript-eslint: 8.39.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) @@ -9365,25 +9098,16 @@ snapshots: '@sveltejs/vite-plugin-svelte-inspector@5.0.0-next.0(@sveltejs/vite-plugin-svelte@6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': dependencies: '@sveltejs/vite-plugin-svelte': 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) svelte: 5.35.5 vite: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte-inspector@5.0.0-next.0(@sveltejs/vite-plugin-svelte@6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': - dependencies: - '@sveltejs/vite-plugin-svelte': 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) - debug: 4.4.1(supports-color@10.1.0) - svelte: 5.35.5 - vite: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) - transitivePeerDependencies: - - supports-color - '@sveltejs/vite-plugin-svelte@6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': dependencies: '@sveltejs/vite-plugin-svelte-inspector': 5.0.0-next.0(@sveltejs/vite-plugin-svelte@6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) deepmerge: 4.3.1 kleur: 4.1.5 magic-string: 0.30.17 @@ -9393,23 +9117,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': - dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.0-next.0(@sveltejs/vite-plugin-svelte@6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)))(svelte@5.35.5)(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) - debug: 4.4.1(supports-color@10.1.0) - deepmerge: 4.3.1 - kleur: 4.1.5 - magic-string: 0.30.17 - svelte: 5.35.5 - vite: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) - vitefu: 1.1.1(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) - transitivePeerDependencies: - - supports-color - '@svitejs/changesets-changelog-github-compact@1.2.0': dependencies: '@changesets/get-github-info': 0.6.0 - dotenv: 16.4.5 + dotenv: 16.6.1 transitivePeerDependencies: - encoding @@ -9460,10 +9171,6 @@ snapshots: dependencies: undici-types: 5.26.5 - '@types/node@20.19.9': - dependencies: - undici-types: 6.21.0 - '@types/normalize-package-data@2.4.4': {} '@types/resolve@1.20.2': {} @@ -9504,28 +9211,19 @@ snapshots: dependencies: '@typescript-eslint/scope-manager': 8.39.0 '@typescript-eslint/types': 8.39.0 - '@typescript-eslint/typescript-estree': 8.39.0(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.39.0(supports-color@10.0.0)(typescript@5.8.3) '@typescript-eslint/visitor-keys': 8.39.0 - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) eslint: 9.29.0(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.37.0(supports-color@10.1.0)(typescript@5.8.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.37.0(typescript@5.8.3) - '@typescript-eslint/types': 8.37.0 - debug: 4.4.1(supports-color@10.1.0) - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/project-service@8.39.0(typescript@5.8.3)': + '@typescript-eslint/project-service@8.39.0(supports-color@10.0.0)(typescript@5.8.3)': dependencies: '@typescript-eslint/tsconfig-utils': 8.39.0(typescript@5.8.3) '@typescript-eslint/types': 8.39.0 - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -9535,10 +9233,6 @@ snapshots: '@typescript-eslint/types': 8.39.0 '@typescript-eslint/visitor-keys': 8.39.0 - '@typescript-eslint/tsconfig-utils@8.37.0(typescript@5.8.3)': - dependencies: - typescript: 5.8.3 - '@typescript-eslint/tsconfig-utils@8.39.0(typescript@5.8.3)': dependencies: typescript: 5.8.3 @@ -9546,42 +9240,24 @@ snapshots: '@typescript-eslint/type-utils@8.39.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@typescript-eslint/types': 8.39.0 - '@typescript-eslint/typescript-estree': 8.39.0(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.39.0(supports-color@10.0.0)(typescript@5.8.3) '@typescript-eslint/utils': 8.39.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) eslint: 9.29.0(jiti@2.4.2) ts-api-utils: 2.1.0(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.37.0': {} - '@typescript-eslint/types@8.39.0': {} - '@typescript-eslint/typescript-estree@8.37.0(supports-color@10.1.0)(typescript@5.8.3)': + '@typescript-eslint/typescript-estree@8.39.0(supports-color@10.0.0)(typescript@5.8.3)': dependencies: - '@typescript-eslint/project-service': 8.37.0(supports-color@10.1.0)(typescript@5.8.3) - '@typescript-eslint/tsconfig-utils': 8.37.0(typescript@5.8.3) - '@typescript-eslint/types': 8.37.0 - '@typescript-eslint/visitor-keys': 8.37.0 - debug: 4.4.1(supports-color@10.1.0) - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@5.8.3) - typescript: 5.8.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/typescript-estree@8.39.0(typescript@5.8.3)': - dependencies: - '@typescript-eslint/project-service': 8.39.0(typescript@5.8.3) + '@typescript-eslint/project-service': 8.39.0(supports-color@10.0.0)(typescript@5.8.3) '@typescript-eslint/tsconfig-utils': 8.39.0(typescript@5.8.3) '@typescript-eslint/types': 8.39.0 '@typescript-eslint/visitor-keys': 8.39.0 - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 @@ -9596,17 +9272,12 @@ snapshots: '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) '@typescript-eslint/scope-manager': 8.39.0 '@typescript-eslint/types': 8.39.0 - '@typescript-eslint/typescript-estree': 8.39.0(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.39.0(supports-color@10.0.0)(typescript@5.8.3) eslint: 9.29.0(jiti@2.4.2) typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.37.0': - dependencies: - '@typescript-eslint/types': 8.37.0 - eslint-visitor-keys: 4.2.1 - '@typescript-eslint/visitor-keys@8.39.0': dependencies: '@typescript-eslint/types': 8.39.0 @@ -9614,7 +9285,7 @@ snapshots: '@vercel/nft@0.29.4(rollup@4.44.0)': dependencies: - '@mapbox/node-pre-gyp': 2.0.0(supports-color@10.1.0) + '@mapbox/node-pre-gyp': 2.0.0(supports-color@10.0.0) '@rollup/pluginutils': 5.1.3(rollup@4.44.0) acorn: 8.15.0 acorn-import-attributes: 1.9.5(acorn@8.15.0) @@ -9633,7 +9304,7 @@ snapshots: '@vercel/nft@0.30.0(rollup@4.44.0)': dependencies: - '@mapbox/node-pre-gyp': 2.0.0(supports-color@10.1.0) + '@mapbox/node-pre-gyp': 2.0.0(supports-color@10.0.0) '@rollup/pluginutils': 5.1.3(rollup@4.44.0) acorn: 8.15.0 acorn-import-attributes: 1.9.5(acorn@8.15.0) @@ -9650,9 +9321,9 @@ snapshots: - rollup - supports-color - '@vercel/nft@0.30.0(supports-color@10.1.0)': + '@vercel/nft@0.30.0(supports-color@10.0.0)': dependencies: - '@mapbox/node-pre-gyp': 2.0.0(supports-color@10.1.0) + '@mapbox/node-pre-gyp': 2.0.0(supports-color@10.0.0) '@rollup/pluginutils': 5.1.3(rollup@4.44.0) acorn: 8.15.0 acorn-import-attributes: 1.9.5(acorn@8.15.0) @@ -9685,14 +9356,6 @@ snapshots: optionalDependencies: vite: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) - '@vitest/mocker@3.2.3(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0))': - dependencies: - '@vitest/spy': 3.2.3 - estree-walker: 3.0.3 - magic-string: 0.30.17 - optionalDependencies: - vite: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) - '@vitest/pretty-format@3.2.3': dependencies: tinyrainbow: 2.0.0 @@ -9856,10 +9519,6 @@ snapshots: acorn-walk@8.3.2: {} - acorn-walk@8.3.4: - dependencies: - acorn: 8.15.0 - acorn@8.14.0: {} acorn@8.15.0: {} @@ -10153,7 +9812,7 @@ snapshots: chokidar@4.0.3: dependencies: - readdirp: 4.0.1 + readdirp: 4.1.2 chownr@3.0.0: {} @@ -10287,8 +9946,6 @@ snapshots: graceful-fs: 4.2.11 xdg-basedir: 5.1.0 - consola@3.2.3: {} - consola@3.4.2: {} console-clear@1.1.1: {} @@ -10354,10 +10011,10 @@ snapshots: dependencies: uncrypto: 0.1.3 - css-select@5.2.2: + css-select@5.1.0: dependencies: boolbase: 1.0.0 - css-what: 6.2.2 + css-what: 6.1.0 domhandler: 5.0.3 domutils: 3.2.2 nth-check: 2.1.1 @@ -10372,7 +10029,7 @@ snapshots: mdn-data: 2.12.2 source-map-js: 1.2.1 - css-what@6.2.2: {} + css-what@6.1.0: {} cssesc@3.0.0: {} @@ -10394,11 +10051,11 @@ snapshots: dependencies: ms: 2.0.0 - debug@4.4.1(supports-color@10.1.0): + debug@4.4.1(supports-color@10.0.0): dependencies: ms: 2.1.3 optionalDependencies: - supports-color: 10.1.0 + supports-color: 10.0.0 decache@4.6.2: dependencies: @@ -10485,16 +10142,16 @@ snapshots: detective-stylus@5.0.1: {} - detective-typescript@14.0.0(supports-color@10.1.0)(typescript@5.8.3): + detective-typescript@14.0.0(supports-color@10.0.0)(typescript@5.8.3): dependencies: - '@typescript-eslint/typescript-estree': 8.37.0(supports-color@10.1.0)(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.39.0(supports-color@10.0.0)(typescript@5.8.3) ast-module-types: 6.0.1 node-source-walk: 7.0.1 typescript: 5.8.3 transitivePeerDependencies: - supports-color - detective-vue2@2.2.0(supports-color@10.1.0)(typescript@5.8.3): + detective-vue2@2.2.0(supports-color@10.0.0)(typescript@5.8.3): dependencies: '@dependents/detective-less': 5.0.1 '@vue/compiler-sfc': 3.5.16 @@ -10502,7 +10159,7 @@ snapshots: detective-sass: 6.0.1 detective-scss: 5.0.1 detective-stylus: 5.0.1 - detective-typescript: 14.0.0(supports-color@10.1.0)(typescript@5.8.3) + detective-typescript: 14.0.0(supports-color@10.0.0)(typescript@5.8.3) typescript: 5.8.3 transitivePeerDependencies: - supports-color @@ -10539,8 +10196,6 @@ snapshots: dependencies: type-fest: 4.41.0 - dotenv@16.4.5: {} - dotenv@16.6.1: {} dropcss@1.0.16: {} @@ -10763,7 +10418,7 @@ snapshots: - supports-color - typescript - eslint-plugin-svelte@3.9.3(eslint@9.29.0(jiti@2.4.2))(svelte@5.35.5)(ts-node@10.9.2(@types/node@20.19.9)(typescript@5.8.3)): + eslint-plugin-svelte@3.9.3(eslint@9.29.0(jiti@2.4.2))(svelte@5.35.5)(ts-node@10.9.2(@types/node@18.19.119)(typescript@5.8.3)): dependencies: '@eslint-community/eslint-utils': 4.7.0(eslint@9.29.0(jiti@2.4.2)) '@jridgewell/sourcemap-codec': 1.5.4 @@ -10772,10 +10427,10 @@ snapshots: globals: 16.3.0 known-css-properties: 0.37.0 postcss: 8.5.6 - postcss-load-config: 3.1.4(postcss@8.5.6)(ts-node@10.9.2(@types/node@20.19.9)(typescript@5.8.3)) + postcss-load-config: 3.1.4(postcss@8.5.6)(ts-node@10.9.2(@types/node@18.19.119)(typescript@5.8.3)) postcss-safe-parser: 7.0.1(postcss@8.5.6) semver: 7.7.2 - svelte-eslint-parser: 1.2.0(svelte@5.35.5) + svelte-eslint-parser: 1.3.1(svelte@5.35.5) optionalDependencies: svelte: 5.35.5 transitivePeerDependencies: @@ -10799,7 +10454,7 @@ snapshots: '@eslint/core': 0.14.0 '@eslint/eslintrc': 3.3.1 '@eslint/js': 9.29.0 - '@eslint/plugin-kit': 0.3.2 + '@eslint/plugin-kit': 0.3.4 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 @@ -10808,7 +10463,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -10961,7 +10616,7 @@ snapshots: extract-zip@2.0.1: dependencies: - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -11140,9 +10795,9 @@ snapshots: dependencies: from2: 2.3.0 - follow-redirects@1.15.11(debug@4.4.1): + follow-redirects@1.15.9(debug@4.4.1): optionalDependencies: - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) foreground-child@3.3.0: dependencies: @@ -11208,9 +10863,7 @@ snapshots: hasown: 2.0.2 math-intrinsics: 1.1.0 - get-package-name@2.2.0: {} - - get-port-please@3.2.0: {} + get-port-please@3.1.2: {} get-port@5.1.1: {} @@ -11328,14 +10981,14 @@ snapshots: graphemer@1.4.0: {} - h3@1.15.4: + h3@1.15.3: dependencies: cookie-es: 1.2.2 crossws: 0.3.5 defu: 6.1.4 destr: 2.0.5 iron-webcrypto: 1.2.1 - node-mock-http: 1.0.2 + node-mock-http: 1.0.0 radix3: 1.1.2 ufo: 1.6.1 uncrypto: 0.1.3 @@ -11393,7 +11046,7 @@ snapshots: http-proxy@1.18.1(debug@4.4.1): dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.11(debug@4.4.1) + follow-redirects: 1.15.9(debug@4.4.1) requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -11405,10 +11058,10 @@ snapshots: quick-lru: 5.1.1 resolve-alpn: 1.2.1 - https-proxy-agent@7.0.6(supports-color@10.1.0): + https-proxy-agent@7.0.6(supports-color@10.0.0): dependencies: agent-base: 7.1.3 - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) transitivePeerDependencies: - supports-color @@ -11503,7 +11156,7 @@ snapshots: defu: 6.1.4 destr: 2.0.5 etag: 1.8.1 - h3: 1.15.4 + h3: 1.15.3 image-meta: 0.2.1 listhen: 1.9.0 ofetch: 1.4.1 @@ -11725,12 +11378,12 @@ snapshots: kuler@2.0.0: {} - ky@1.8.2: {} + ky@1.8.1: {} lambda-local@2.2.0: dependencies: commander: 10.0.1 - dotenv: 16.4.5 + dotenv: 16.6.1 winston: 3.17.0 latest-version@9.0.0: @@ -11811,8 +11464,8 @@ snapshots: consola: 3.4.2 crossws: 0.3.5 defu: 6.1.4 - get-port-please: 3.2.0 - h3: 1.15.4 + get-port-please: 3.1.2 + h3: 1.15.3 http-shutdown: 1.2.2 jiti: 2.4.2 mlly: 1.7.4 @@ -12070,7 +11723,7 @@ snapshots: mute-stream@0.0.8: {} - nan@2.23.0: + nan@2.22.2: optional: true nanoid@3.3.11: {} @@ -12083,12 +11736,12 @@ snapshots: negotiator@0.6.3: {} - netlify-cli@23.1.1(@types/node@20.19.9)(picomatch@4.0.3): + netlify-cli@23.1.1(@types/node@18.19.119)(picomatch@4.0.3): dependencies: '@fastify/static': 7.0.4 '@netlify/api': 14.0.3 '@netlify/blobs': 10.0.8 - '@netlify/build': 35.0.3(@opentelemetry/api@1.8.0)(@types/node@20.19.9)(picomatch@4.0.3) + '@netlify/build': 35.0.3(@opentelemetry/api@1.8.0)(@types/node@18.19.119)(picomatch@4.0.3) '@netlify/build-info': 10.0.7 '@netlify/config': 24.0.1 '@netlify/dev-utils': 4.1.1 @@ -12115,7 +11768,7 @@ snapshots: content-type: 1.0.5 cookie: 1.0.2 cron-parser: 4.9.0 - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) decache: 4.6.2 dot-prop: 9.0.0 dotenv: 16.6.1 @@ -12137,7 +11790,7 @@ snapshots: gitconfiglocal: 2.1.0 http-proxy: 1.18.1(debug@4.4.1) http-proxy-middleware: 2.0.9(debug@4.4.1) - https-proxy-agent: 7.0.6(supports-color@10.1.0) + https-proxy-agent: 7.0.6(supports-color@10.0.0) inquirer: 8.2.6 inquirer-autocomplete-prompt: 1.4.0(inquirer@8.2.6) ipx: 3.1.1(@netlify/blobs@10.0.8) @@ -12220,7 +11873,7 @@ snapshots: node-domexception@1.0.0: {} - node-fetch-native@1.6.7: {} + node-fetch-native@1.6.6: {} node-fetch@2.7.0: dependencies: @@ -12236,7 +11889,7 @@ snapshots: node-gyp-build@4.8.0: {} - node-mock-http@1.0.2: {} + node-mock-http@1.0.0: {} node-source-walk@7.0.1: dependencies: @@ -12290,7 +11943,7 @@ snapshots: ofetch@1.4.1: dependencies: destr: 2.0.5 - node-fetch-native: 1.6.7 + node-fetch-native: 1.6.6 ufo: 1.6.1 ohash@2.0.11: {} @@ -12434,7 +12087,7 @@ snapshots: package-json@10.0.1: dependencies: - ky: 1.8.2 + ky: 1.8.1 registry-auth-token: 5.1.0 registry-url: 6.0.1 semver: 7.7.2 @@ -12562,15 +12215,6 @@ snapshots: optionalDependencies: postcss: 8.5.6 ts-node: 10.9.2(@types/node@18.19.119)(typescript@5.8.3) - optional: true - - postcss-load-config@3.1.4(postcss@8.5.6)(ts-node@10.9.2(@types/node@20.19.9)(typescript@5.8.3)): - dependencies: - lilconfig: 2.1.0 - yaml: 1.10.2 - optionalDependencies: - postcss: 8.5.6 - ts-node: 10.9.2(@types/node@20.19.9)(typescript@5.8.3) postcss-safe-parser@7.0.1(postcss@8.5.6): dependencies: @@ -12598,7 +12242,7 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - precinct@12.2.0(supports-color@10.1.0): + precinct@12.2.0(supports-color@10.0.0): dependencies: '@dependents/detective-less': 5.0.1 commander: 12.1.0 @@ -12609,8 +12253,8 @@ snapshots: detective-sass: 6.0.1 detective-scss: 5.0.1 detective-stylus: 5.0.1 - detective-typescript: 14.0.0(supports-color@10.1.0)(typescript@5.8.3) - detective-vue2: 2.2.0(supports-color@10.1.0)(typescript@5.8.3) + detective-typescript: 14.0.0(supports-color@10.0.0)(typescript@5.8.3) + detective-vue2: 2.2.0(supports-color@10.0.0)(typescript@5.8.3) module-definition: 6.0.1 node-source-walk: 7.0.1 postcss: 8.5.6 @@ -12793,8 +12437,6 @@ snapshots: dependencies: minimatch: 5.1.6 - readdirp@4.0.1: {} - readdirp@4.1.2: {} real-require@0.2.0: {} @@ -12821,7 +12463,7 @@ snapshots: require-in-the-middle@7.5.2: dependencies: - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) module-details-from-path: 1.0.4 resolve: 1.22.8 transitivePeerDependencies: @@ -13011,33 +12653,6 @@ snapshots: '@img/sharp-win32-x64': 0.33.5 optional: true - sharp@0.34.1: - dependencies: - color: 4.2.3 - detect-libc: 2.0.4 - semver: 7.7.2 - optionalDependencies: - '@img/sharp-darwin-arm64': 0.34.1 - '@img/sharp-darwin-x64': 0.34.1 - '@img/sharp-libvips-darwin-arm64': 1.1.0 - '@img/sharp-libvips-darwin-x64': 1.1.0 - '@img/sharp-libvips-linux-arm': 1.1.0 - '@img/sharp-libvips-linux-arm64': 1.1.0 - '@img/sharp-libvips-linux-ppc64': 1.1.0 - '@img/sharp-libvips-linux-s390x': 1.1.0 - '@img/sharp-libvips-linux-x64': 1.1.0 - '@img/sharp-libvips-linuxmusl-arm64': 1.1.0 - '@img/sharp-libvips-linuxmusl-x64': 1.1.0 - '@img/sharp-linux-arm': 0.34.1 - '@img/sharp-linux-arm64': 0.34.1 - '@img/sharp-linux-s390x': 0.34.1 - '@img/sharp-linux-x64': 0.34.1 - '@img/sharp-linuxmusl-arm64': 0.34.1 - '@img/sharp-linuxmusl-x64': 0.34.1 - '@img/sharp-wasm32': 0.34.1 - '@img/sharp-win32-ia32': 0.34.1 - '@img/sharp-win32-x64': 0.34.1 - sharp@0.34.3: dependencies: color: 4.2.3 @@ -13283,7 +12898,7 @@ snapshots: stubborn-fs@1.2.5: {} - supports-color@10.1.0: {} + supports-color@10.0.0: {} supports-color@7.2.0: dependencies: @@ -13308,7 +12923,7 @@ snapshots: transitivePeerDependencies: - picomatch - svelte-eslint-parser@1.2.0(svelte@5.35.5): + svelte-eslint-parser@1.3.1(svelte@5.35.5): dependencies: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -13360,9 +12975,9 @@ snapshots: svgo@4.0.0: dependencies: commander: 11.1.0 - css-select: 5.2.2 + css-select: 5.1.0 css-tree: 3.1.0 - css-what: 6.2.2 + css-what: 6.1.0 csso: 5.0.5 picocolors: 1.1.1 sax: 1.4.1 @@ -13490,26 +13105,7 @@ snapshots: '@tsconfig/node16': 1.0.4 '@types/node': 18.19.119 acorn: 8.15.0 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.8.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - optional: true - - ts-node@10.9.2(@types/node@20.19.9)(typescript@5.8.3): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 20.19.9 - acorn: 8.15.0 - acorn-walk: 8.3.4 + acorn-walk: 8.3.2 arg: 4.1.3 create-require: 1.1.1 diff: 4.0.2 @@ -13539,7 +13135,7 @@ snapshots: dependencies: '@typescript-eslint/eslint-plugin': 8.39.0(@typescript-eslint/parser@8.39.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3))(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) '@typescript-eslint/parser': 8.39.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) - '@typescript-eslint/typescript-estree': 8.39.0(typescript@5.8.3) + '@typescript-eslint/typescript-estree': 8.39.0(supports-color@10.0.0)(typescript@5.8.3) '@typescript-eslint/utils': 8.39.0(eslint@9.29.0(jiti@2.4.2))(typescript@5.8.3) eslint: 9.29.0(jiti@2.4.2) typescript: 5.8.3 @@ -13565,8 +13161,6 @@ snapshots: undici-types@5.26.5: {} - undici-types@6.21.0: {} - undici@5.29.0: dependencies: '@fastify/busboy': 2.1.1 @@ -13590,7 +13184,7 @@ snapshots: unix-dgram@2.0.6: dependencies: bindings: 1.5.0 - nan: 2.23.0 + nan: 2.22.2 optional: true unixify@1.0.0: @@ -13604,9 +13198,9 @@ snapshots: anymatch: 3.1.3 chokidar: 4.0.3 destr: 2.0.5 - h3: 1.15.4 + h3: 1.15.3 lru-cache: 10.4.3 - node-fetch-native: 1.6.7 + node-fetch-native: 1.6.6 ofetch: 1.4.1 ufo: 1.6.1 optionalDependencies: @@ -13671,14 +13265,14 @@ snapshots: dependencies: '@rollup/pluginutils': 5.1.3(rollup@4.44.0) imagetools-core: 7.1.0 - sharp: 0.34.1 + sharp: 0.34.3 transitivePeerDependencies: - rollup vite-node@3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0): dependencies: cac: 6.7.14 - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) es-module-lexer: 1.7.0 pathe: 2.0.3 vite: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) @@ -13696,30 +13290,9 @@ snapshots: - tsx - yaml - vite-node@3.2.3(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0): - dependencies: - cac: 6.7.14 - debug: 4.4.1(supports-color@10.1.0) - es-module-lexer: 1.7.0 - pathe: 2.0.3 - vite: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) - transitivePeerDependencies: - - '@types/node' - - jiti - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0): dependencies: - esbuild: 0.25.5 + esbuild: 0.25.6 fdir: 6.4.6(picomatch@4.0.3) picomatch: 4.0.3 postcss: 8.5.6 @@ -13732,29 +13305,10 @@ snapshots: lightningcss: 1.30.1 yaml: 2.8.0 - vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0): - dependencies: - esbuild: 0.25.5 - fdir: 6.4.6(picomatch@4.0.3) - picomatch: 4.0.3 - postcss: 8.5.6 - rollup: 4.44.0 - tinyglobby: 0.2.14 - optionalDependencies: - '@types/node': 20.19.9 - fsevents: 2.3.3 - jiti: 2.4.2 - lightningcss: 1.30.1 - yaml: 2.8.0 - vitefu@1.1.1(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)): optionalDependencies: vite: 6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) - vitefu@1.1.1(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)): - optionalDependencies: - vite: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) - vitest@3.2.3(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0): dependencies: '@types/chai': 5.2.2 @@ -13766,7 +13320,7 @@ snapshots: '@vitest/spy': 3.2.3 '@vitest/utils': 3.2.3 chai: 5.2.0 - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) expect-type: 1.2.1 magic-string: 0.30.17 pathe: 2.0.3 @@ -13796,52 +13350,11 @@ snapshots: - tsx - yaml - vitest@3.2.3(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0): - dependencies: - '@types/chai': 5.2.2 - '@vitest/expect': 3.2.3 - '@vitest/mocker': 3.2.3(vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) - '@vitest/pretty-format': 3.2.3 - '@vitest/runner': 3.2.3 - '@vitest/snapshot': 3.2.3 - '@vitest/spy': 3.2.3 - '@vitest/utils': 3.2.3 - chai: 5.2.0 - debug: 4.4.1(supports-color@10.1.0) - expect-type: 1.2.1 - magic-string: 0.30.17 - pathe: 2.0.3 - picomatch: 4.0.3 - std-env: 3.9.0 - tinybench: 2.9.0 - tinyexec: 0.3.2 - tinyglobby: 0.2.14 - tinypool: 1.1.0 - tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) - vite-node: 3.2.3(@types/node@20.19.9)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 20.19.9 - transitivePeerDependencies: - - jiti - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - wait-port@1.1.0: dependencies: chalk: 4.1.2 commander: 9.5.0 - debug: 4.4.1(supports-color@10.1.0) + debug: 4.4.1(supports-color@10.0.0) transitivePeerDependencies: - supports-color @@ -14025,4 +13538,4 @@ snapshots: zod@3.25.56: {} - zod@4.0.15: {} + zod@4.0.14: {} From 587be2264b81fec12e4cef54ae9be6e3548f8e5e Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 7 Aug 2025 13:19:55 -0600 Subject: [PATCH 20/74] chore: catalog node types --- packages/adapter-auto/package.json | 2 +- packages/adapter-cloudflare/package.json | 2 +- packages/adapter-netlify/package.json | 2 +- packages/adapter-node/package.json | 2 +- packages/adapter-static/package.json | 2 +- packages/adapter-vercel/package.json | 2 +- packages/enhanced-img/package.json | 2 +- packages/kit/package.json | 2 +- packages/package/package.json | 2 +- pnpm-lock.yaml | 21 ++++++++++++--------- pnpm-workspace.yaml | 1 + 11 files changed, 22 insertions(+), 18 deletions(-) diff --git a/packages/adapter-auto/package.json b/packages/adapter-auto/package.json index bfac023171db..a835d30591ce 100644 --- a/packages/adapter-auto/package.json +++ b/packages/adapter-auto/package.json @@ -42,7 +42,7 @@ "devDependencies": { "@sveltejs/kit": "workspace:^", "@sveltejs/vite-plugin-svelte": "catalog:", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "typescript": "^5.3.3", "vitest": "catalog:" }, diff --git a/packages/adapter-cloudflare/package.json b/packages/adapter-cloudflare/package.json index 916e31daf005..20ef13541993 100644 --- a/packages/adapter-cloudflare/package.json +++ b/packages/adapter-cloudflare/package.json @@ -50,7 +50,7 @@ "devDependencies": { "@playwright/test": "catalog:", "@sveltejs/kit": "workspace:^", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "esbuild": "^0.25.4", "typescript": "^5.3.3", "vitest": "catalog:" diff --git a/packages/adapter-netlify/package.json b/packages/adapter-netlify/package.json index 7ea1272635c0..1e5fd08b1b50 100644 --- a/packages/adapter-netlify/package.json +++ b/packages/adapter-netlify/package.json @@ -55,7 +55,7 @@ "@rollup/plugin-node-resolve": "^16.0.0", "@sveltejs/kit": "workspace:^", "@sveltejs/vite-plugin-svelte": "catalog:", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "@types/set-cookie-parser": "^2.4.7", "rollup": "^4.14.2", "typescript": "^5.3.3", diff --git a/packages/adapter-node/package.json b/packages/adapter-node/package.json index 2f0bc780d3af..68a9b37ab71f 100644 --- a/packages/adapter-node/package.json +++ b/packages/adapter-node/package.json @@ -45,7 +45,7 @@ "@polka/url": "^1.0.0-next.28", "@sveltejs/kit": "workspace:^", "@sveltejs/vite-plugin-svelte": "catalog:", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "polka": "^1.0.0-next.28", "sirv": "^3.0.0", "typescript": "^5.3.3", diff --git a/packages/adapter-static/package.json b/packages/adapter-static/package.json index f5676f7ec003..b7e8db6b7a69 100644 --- a/packages/adapter-static/package.json +++ b/packages/adapter-static/package.json @@ -42,7 +42,7 @@ "@playwright/test": "catalog:", "@sveltejs/kit": "workspace:^", "@sveltejs/vite-plugin-svelte": "catalog:", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "sirv": "^3.0.0", "svelte": "^5.35.5", "typescript": "^5.3.3", diff --git a/packages/adapter-vercel/package.json b/packages/adapter-vercel/package.json index 0db6db93d9b3..d8a843b7ab03 100644 --- a/packages/adapter-vercel/package.json +++ b/packages/adapter-vercel/package.json @@ -46,7 +46,7 @@ "devDependencies": { "@sveltejs/kit": "workspace:^", "@sveltejs/vite-plugin-svelte": "catalog:", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "typescript": "^5.3.3", "vitest": "catalog:" }, diff --git a/packages/enhanced-img/package.json b/packages/enhanced-img/package.json index ee298abf3251..e0df5c9253b8 100644 --- a/packages/enhanced-img/package.json +++ b/packages/enhanced-img/package.json @@ -45,7 +45,7 @@ "devDependencies": { "@sveltejs/vite-plugin-svelte": "catalog:", "@types/estree": "^1.0.5", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "rollup": "^4.27.4", "svelte": "^5.35.5", "typescript": "^5.6.3", diff --git a/packages/kit/package.json b/packages/kit/package.json index 4eb23e01701b..748366a4602b 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -37,7 +37,7 @@ "@playwright/test": "catalog:", "@sveltejs/vite-plugin-svelte": "catalog:", "@types/connect": "^3.4.38", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "@types/set-cookie-parser": "^2.4.7", "dts-buddy": "^0.6.2", "rollup": "^4.14.2", diff --git a/packages/package/package.json b/packages/package/package.json index 6145573ad847..87f40b34634b 100644 --- a/packages/package/package.json +++ b/packages/package/package.json @@ -28,7 +28,7 @@ }, "devDependencies": { "@sveltejs/vite-plugin-svelte": "catalog:", - "@types/node": "^18.19.119", + "@types/node": "catalog:", "@types/semver": "^7.5.6", "prettier": "^3.1.1", "svelte": "^5.35.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 62e3e2b0ebe8..5fc2aebeec88 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,6 +12,9 @@ catalogs: '@sveltejs/vite-plugin-svelte': specifier: ^6.0.0-next.3 version: 6.0.0-next.3 + '@types/node': + specifier: ^18.19.119 + version: 18.19.119 cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -60,7 +63,7 @@ importers: specifier: 'catalog:' version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) '@types/node': - specifier: ^18.19.119 + specifier: 'catalog:' version: 18.19.119 typescript: specifier: ^5.3.3 @@ -88,7 +91,7 @@ importers: specifier: workspace:^ version: link:../kit '@types/node': - specifier: ^18.19.119 + specifier: 'catalog:' version: 18.19.119 esbuild: specifier: ^0.25.4 @@ -179,7 +182,7 @@ importers: specifier: 'catalog:' version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) '@types/node': - specifier: ^18.19.119 + specifier: 'catalog:' version: 18.19.119 '@types/set-cookie-parser': specifier: ^2.4.7 @@ -255,7 +258,7 @@ importers: specifier: 'catalog:' version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) '@types/node': - specifier: ^18.19.119 + specifier: 'catalog:' version: 18.19.119 polka: specifier: ^1.0.0-next.28 @@ -282,7 +285,7 @@ importers: specifier: 'catalog:' version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) '@types/node': - specifier: ^18.19.119 + specifier: 'catalog:' version: 18.19.119 sirv: specifier: ^3.0.0 @@ -352,7 +355,7 @@ importers: specifier: 'catalog:' version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) '@types/node': - specifier: ^18.19.119 + specifier: 'catalog:' version: 18.19.119 typescript: specifier: ^5.3.3 @@ -397,7 +400,7 @@ importers: specifier: ^1.0.5 version: 1.0.8 '@types/node': - specifier: ^18.19.119 + specifier: 'catalog:' version: 18.19.119 rollup: specifier: ^4.27.4 @@ -470,7 +473,7 @@ importers: specifier: ^3.4.38 version: 3.4.38 '@types/node': - specifier: ^18.19.119 + specifier: 'catalog:' version: 18.19.119 '@types/set-cookie-parser': specifier: ^2.4.7 @@ -1197,7 +1200,7 @@ importers: specifier: 'catalog:' version: 6.0.0-next.3(svelte@5.35.5)(vite@6.3.5(@types/node@18.19.119)(jiti@2.4.2)(lightningcss@1.30.1)(yaml@2.8.0)) '@types/node': - specifier: ^18.19.119 + specifier: 'catalog:' version: 18.19.119 '@types/semver': specifier: ^7.5.6 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 5552fdfb0ded..c520b3835bcb 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -14,6 +14,7 @@ packages: catalog: '@playwright/test': '^1.51.1' '@sveltejs/vite-plugin-svelte': '^6.0.0-next.3' + '@types/node': '^18.19.119' 'cross-env': '^7.0.3' 'vitest': '^3.2.3' 'vite': '^6.3.5' From 83a24aa0ef1cfa48cf14eead2eb135e47b4cf8fa Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 7 Aug 2025 14:24:45 -0600 Subject: [PATCH 21/74] upstream --- packages/kit/src/core/config/index.js | 2 ++ packages/kit/src/core/config/index.spec.js | 3 ++ packages/kit/src/core/config/options.js | 3 ++ packages/kit/src/exports/public.d.ts | 13 +++++++++ packages/kit/src/exports/vite/dev/index.js | 7 +++-- packages/kit/src/runtime/server/respond.js | 27 ++++++++++++++++- packages/kit/src/runtime/telemetry/otel.js | 29 ++++++++++--------- .../runtime/telemetry/otel.missing.spec.js | 3 +- .../telemetry/record_span.enabled.spec.js | 11 ++++--- .../kit/src/runtime/telemetry/record_span.js | 2 +- packages/kit/types/index.d.ts | 13 +++++++++ 11 files changed, 91 insertions(+), 22 deletions(-) diff --git a/packages/kit/src/core/config/index.js b/packages/kit/src/core/config/index.js index 7fc38bc483dd..af18dfee10bf 100644 --- a/packages/kit/src/core/config/index.js +++ b/packages/kit/src/core/config/index.js @@ -105,6 +105,8 @@ function process_config(config, { cwd = process.cwd() } = {}) { validated.kit.files.hooks.client = path.resolve(cwd, validated.kit.files.hooks.client); validated.kit.files.hooks.server = path.resolve(cwd, validated.kit.files.hooks.server); validated.kit.files.hooks.universal = path.resolve(cwd, validated.kit.files.hooks.universal); + } else if (key === 'tracing') { + validated.kit.files.tracing.server = path.resolve(cwd, validated.kit.files.tracing.server); } else { // @ts-expect-error validated.kit.files[key] = path.resolve(cwd, validated.kit.files[key]); diff --git a/packages/kit/src/core/config/index.spec.js b/packages/kit/src/core/config/index.spec.js index c8d3b04b51fd..63463eeedfa9 100644 --- a/packages/kit/src/core/config/index.spec.js +++ b/packages/kit/src/core/config/index.spec.js @@ -94,6 +94,9 @@ const get_defaults = (prefix = '') => ({ appTemplate: join(prefix, 'src/app.html'), errorTemplate: join(prefix, 'src/error.html') }, + tracing: { + server: join(prefix, 'src/tracing.server') + }, inlineStyleThreshold: 0, moduleExtensions: ['.js', '.ts'], output: { preloadStrategy: 'modulepreload', bundleStrategy: 'split' }, diff --git a/packages/kit/src/core/config/options.js b/packages/kit/src/core/config/options.js index 12107e077c9b..646240171b08 100644 --- a/packages/kit/src/core/config/options.js +++ b/packages/kit/src/core/config/options.js @@ -134,6 +134,9 @@ const options = object( server: string(join('src', 'hooks.server')), universal: string(join('src', 'hooks')) }), + tracing: object({ + server: string(join('src', 'tracing.server')) + }), lib: string(join('src', 'lib')), params: string(join('src', 'params')), routes: string(join('src', 'routes')), diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 4729a7ce2ff3..49e7cffb8754 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -51,6 +51,12 @@ export interface Adapter { * @param details.config The merged route config */ read?: (details: { config: any; route: { id: string } }) => boolean; + + /** + * Test support for `tracing`. To pass, the adapter must support `tracing.server.js` and + * also deploy to a platform that supports `@opentelemetry/api`. + */ + tracing?: () => boolean; }; /** * Creates an `Emulator`, which allows the adapter to influence the environment @@ -453,6 +459,13 @@ export interface KitConfig { */ universal?: string; }; + /** + * the location of your server tracing file + * @default "src/tracing.server" + */ + tracing?: { + server?: string; + }; /** * your app's internal library, accessible throughout the codebase as `$lib` * @default "src/lib" diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index a5f211efa9af..be1644dfb435 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -376,7 +376,7 @@ export async function dev(vite, vite_config, svelte_config) { sync.update(svelte_config, manifest_data, file); }); - const { appTemplate, errorTemplate, serviceWorker, hooks } = svelte_config.kit.files; + const { appTemplate, errorTemplate, serviceWorker, hooks, tracing } = svelte_config.kit.files; // vite client only executes a full reload if the triggering html file path is index.html // kit defaults to src/app.html, so unless user changed that to index.html @@ -394,7 +394,8 @@ export async function dev(vite, vite_config, svelte_config) { file === appTemplate || file === errorTemplate || file.startsWith(serviceWorker) || - file.startsWith(hooks.server) + file.startsWith(hooks.server) || + file.startsWith(tracing.server) ) { sync.server(svelte_config); } @@ -501,6 +502,8 @@ export async function dev(vite, vite_config, svelte_config) { return; } + await vite.ssrLoadModule(tracing.server); + // we have to import `Server` before calling `set_assets` const { Server } = /** @type {import('types').ServerModule} */ ( await vite.ssrLoadModule(`${runtime_base}/server/index.js`, { fixStacktrace: true }) diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index 4735ee201653..54882f3ff37b 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -38,6 +38,7 @@ import { with_event } from '../app/server/event.js'; import { record_span } from '../telemetry/record_span.js'; import { merge_tracing } from '../utils.js'; import { create_event_state, EVENT_STATE } from './event-state.js'; +import { otel } from '../telemetry/otel.js'; /* global __SVELTEKIT_ADAPTER_NAME__ */ /* global __SVELTEKIT_DEV__ */ @@ -57,6 +58,8 @@ const allowed_page_methods = new Set(['GET', 'HEAD', 'OPTIONS']); let warned_on_devtools_json_request = false; +export const respond = propagate_context(internal_respond); + /** * @param {Request} request * @param {import('types').SSROptions} options @@ -64,7 +67,7 @@ let warned_on_devtools_json_request = false; * @param {import('types').SSRState} state * @returns {Promise} */ -export async function respond(request, options, manifest, state) { +export async function internal_respond(request, options, manifest, state) { /** URL but stripped from the potential `/__data.json` suffix and its search param */ const url = new URL(request.url); @@ -697,3 +700,25 @@ export function load_page_nodes(page, manifest) { manifest._.nodes[page.leaf]() ]); } + +/** + * It's likely that, in a distributed system, there are spans starting outside the SvelteKit server -- eg. + * started on the frontend client, or in a service that calls the SvelteKit server. There are standardized + * ways to represent this context in HTTP headers, so we can extract that context and run our tracing inside of it + * so that when our traces are exported, they are associated with the correct parent context. + * @param {typeof internal_respond} fn + * @returns {typeof internal_respond} + */ +function propagate_context(fn) { + return async (req, ...rest) => { + if (otel === null) { + return fn(req, ...rest); + } + + const { propagation, context } = await otel; + const c = propagation.extract(context.active(), Object.fromEntries(req.headers)); + return context.with(c, async () => { + return await fn(req, ...rest); + }); + }; +} diff --git a/packages/kit/src/runtime/telemetry/otel.js b/packages/kit/src/runtime/telemetry/otel.js index 6278d82fe645..5ef6a71ac3e5 100644 --- a/packages/kit/src/runtime/telemetry/otel.js +++ b/packages/kit/src/runtime/telemetry/otel.js @@ -1,18 +1,21 @@ -/** @import { Tracer, SpanStatusCode } from '@opentelemetry/api' */ +/** @import { Tracer, SpanStatusCode, PropagationAPI, ContextAPI } from '@opentelemetry/api' */ -/** @type {{ tracer: Tracer, SpanStatusCode: typeof SpanStatusCode } | null} */ +/** @type {Promise<{ tracer: Tracer, SpanStatusCode: typeof SpanStatusCode, propagation: PropagationAPI, context: ContextAPI }> | null} */ export let otel = null; if (__SVELTEKIT_SERVER_TRACING_ENABLED__) { - try { - const module = await import('@opentelemetry/api'); - otel = { - tracer: module.trace.getTracer('sveltekit'), - SpanStatusCode: module.SpanStatusCode - }; - } catch { - throw new Error( - 'Tracing is enabled (see `config.kit.experimental.tracing.server` in your svelte.config.js), but `@opentelemetry/api` is not available. Have you installed it?' - ); - } + otel = import('@opentelemetry/api') + .then((module) => { + return { + tracer: module.trace.getTracer('sveltekit'), + propagation: module.propagation, + context: module.context, + SpanStatusCode: module.SpanStatusCode + }; + }) + .catch(() => { + throw new Error( + 'Tracing is enabled (see `config.kit.experimental.tracing.server` in your svelte.config.js), but `@opentelemetry/api` is not available. Have you installed it?' + ); + }); } diff --git a/packages/kit/src/runtime/telemetry/otel.missing.spec.js b/packages/kit/src/runtime/telemetry/otel.missing.spec.js index a02a99293cf1..256e9c3f1d9a 100644 --- a/packages/kit/src/runtime/telemetry/otel.missing.spec.js +++ b/packages/kit/src/runtime/telemetry/otel.missing.spec.js @@ -9,7 +9,8 @@ vi.mock('@opentelemetry/api', () => { }); test('otel should throw an error when tracing is enabled but @opentelemetry/api is not available', async () => { - await expect(import('./otel.js')).rejects.toThrow( + const { otel } = await import('./otel.js'); + await expect(otel).rejects.toThrow( 'Tracing is enabled (see `config.kit.experimental.tracing.server` in your svelte.config.js), but `@opentelemetry/api` is not available. Have you installed it?' ); }); diff --git a/packages/kit/src/runtime/telemetry/record_span.enabled.spec.js b/packages/kit/src/runtime/telemetry/record_span.enabled.spec.js index ce10a866d79c..b85a70b812d4 100644 --- a/packages/kit/src/runtime/telemetry/record_span.enabled.spec.js +++ b/packages/kit/src/runtime/telemetry/record_span.enabled.spec.js @@ -30,17 +30,20 @@ const { tracer, span } = vi.hoisted(() => { }); vi.mock(import('./otel.js'), async (original) => { - const { otel } = await original(); + const { otel: unresolved_otel } = await original(); + const otel = await unresolved_otel; if (otel === null) { throw new Error('Problem setting up tests; otel is null'); } return { - otel: { + otel: Promise.resolve({ tracer, - SpanStatusCode: otel.SpanStatusCode - } + SpanStatusCode: otel.SpanStatusCode, + propagation: otel.propagation, + context: otel.context + }) }; }); diff --git a/packages/kit/src/runtime/telemetry/record_span.js b/packages/kit/src/runtime/telemetry/record_span.js index 0f6b7aa3eb66..1bc3fcb6dfed 100644 --- a/packages/kit/src/runtime/telemetry/record_span.js +++ b/packages/kit/src/runtime/telemetry/record_span.js @@ -16,7 +16,7 @@ export async function record_span({ name, attributes, fn }) { return fn(noop_span); } - const { SpanStatusCode, tracer } = otel; + const { SpanStatusCode, tracer } = await otel; return tracer.startActiveSpan(name, { attributes }, async (span) => { try { diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 7d1ff2094047..2d40662c4328 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -28,6 +28,12 @@ declare module '@sveltejs/kit' { * @param details.config The merged route config */ read?: (details: { config: any; route: { id: string } }) => boolean; + + /** + * Test support for `tracing`. To pass, the adapter must support `tracing.server.js` and + * also deploy to a platform that supports `@opentelemetry/api`. + */ + tracing?: () => boolean; }; /** * Creates an `Emulator`, which allows the adapter to influence the environment @@ -430,6 +436,13 @@ declare module '@sveltejs/kit' { */ universal?: string; }; + /** + * the location of your server tracing file + * @default "src/tracing.server" + */ + tracing?: { + server?: string; + }; /** * your app's internal library, accessible throughout the codebase as `$lib` * @default "src/lib" From 874717f0ec93f4596e8206e1293328f4fa3099f3 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 7 Aug 2025 14:36:04 -0600 Subject: [PATCH 22/74] fix: idiocy on my part tbh --- packages/kit/src/core/config/index.spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/kit/src/core/config/index.spec.js b/packages/kit/src/core/config/index.spec.js index 63463eeedfa9..4c8a1be7f876 100644 --- a/packages/kit/src/core/config/index.spec.js +++ b/packages/kit/src/core/config/index.spec.js @@ -87,6 +87,9 @@ const get_defaults = (prefix = '') => ({ server: join(prefix, 'src/hooks.server'), universal: join(prefix, 'src/hooks') }, + tracing: { + server: join(prefix, 'src/tracing.server') + }, lib: join(prefix, 'src/lib'), params: join(prefix, 'src/params'), routes: join(prefix, 'src/routes'), @@ -94,9 +97,6 @@ const get_defaults = (prefix = '') => ({ appTemplate: join(prefix, 'src/app.html'), errorTemplate: join(prefix, 'src/error.html') }, - tracing: { - server: join(prefix, 'src/tracing.server') - }, inlineStyleThreshold: 0, moduleExtensions: ['.js', '.ts'], output: { preloadStrategy: 'modulepreload', bundleStrategy: 'split' }, From 1d06059c243574a062f8ba0f6bbd1032e266bbf0 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Fri, 8 Aug 2025 10:04:22 -0600 Subject: [PATCH 23/74] optionally load tracing, add remote functions --- packages/kit/src/exports/vite/dev/index.js | 6 ++-- packages/kit/src/runtime/server/remote.js | 36 ++++++++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index be1644dfb435..25a5854fec73 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -1,4 +1,4 @@ -import fs from 'node:fs'; +import fs, { existsSync } from 'node:fs'; import path from 'node:path'; import process from 'node:process'; import { URL } from 'node:url'; @@ -502,7 +502,9 @@ export async function dev(vite, vite_config, svelte_config) { return; } - await vite.ssrLoadModule(tracing.server); + if (existsSync(tracing.server)) { + await vite.ssrLoadModule(tracing.server); + } // we have to import `Server` before calling `set_assets` const { Server } = /** @type {import('types').ServerModule} */ ( diff --git a/packages/kit/src/runtime/server/remote.js b/packages/kit/src/runtime/server/remote.js index 6bd087f16ffd..c18070051875 100644 --- a/packages/kit/src/runtime/server/remote.js +++ b/packages/kit/src/runtime/server/remote.js @@ -12,6 +12,24 @@ import { normalize_error } from '../../utils/error.js'; import { check_incorrect_fail_use } from './page/actions.js'; import { DEV } from 'esm-env'; import { get_event_state } from './event-state.js'; +import { record_span } from '../telemetry/record_span.js'; +import { merge_tracing } from '../utils.js'; + +/** @type {typeof handle_remote_call_internal} */ +export async function handle_remote_call(event, options, manifest, id) { + return record_span({ + name: 'sveltekit.remote.call', + attributes: { + 'sveltekit.remote.call.id': id + }, + fn: async (current) => { + const traced_event = merge_tracing(event, current); + return with_event(traced_event, () => + handle_remote_call_internal(event, options, manifest, id) + ); + } + }); +} /** * @param {RequestEvent} event @@ -19,7 +37,7 @@ import { get_event_state } from './event-state.js'; * @param {SSRManifest} manifest * @param {string} id */ -export async function handle_remote_call(event, options, manifest, id) { +export async function handle_remote_call_internal(event, options, manifest, id) { const [hash, name, prerender_args] = id.split('/'); const remotes = manifest._.remotes; @@ -155,13 +173,27 @@ export async function handle_remote_call(event, options, manifest, id) { } } +/** @type {typeof handle_remote_form_post_internal} */ +export async function handle_remote_form_post(event, manifest, id) { + return record_span({ + name: 'sveltekit.remote.form.post', + attributes: { + 'sveltekit.remote.form.post.id': id + }, + fn: async (current) => { + const traced_event = merge_tracing(event, current); + return with_event(traced_event, () => handle_remote_form_post_internal(event, manifest, id)); + } + }); +} + /** * @param {RequestEvent} event * @param {SSRManifest} manifest * @param {string} id * @returns {Promise} */ -export async function handle_remote_form_post(event, manifest, id) { +async function handle_remote_form_post_internal(event, manifest, id) { const [hash, name, action_id] = id.split('/'); const remotes = manifest._.remotes; const module = await remotes[hash]?.(); From 4c95395c25bdaf4b7cae8c708f83b211a0ccedf7 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Fri, 8 Aug 2025 10:19:57 -0600 Subject: [PATCH 24/74] chore: Better attributes for actions --- packages/kit/src/runtime/server/remote.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/kit/src/runtime/server/remote.js b/packages/kit/src/runtime/server/remote.js index c18070051875..77eb14813109 100644 --- a/packages/kit/src/runtime/server/remote.js +++ b/packages/kit/src/runtime/server/remote.js @@ -25,7 +25,7 @@ export async function handle_remote_call(event, options, manifest, id) { fn: async (current) => { const traced_event = merge_tracing(event, current); return with_event(traced_event, () => - handle_remote_call_internal(event, options, manifest, id) + handle_remote_call_internal(traced_event, options, manifest, id) ); } }); @@ -37,7 +37,7 @@ export async function handle_remote_call(event, options, manifest, id) { * @param {SSRManifest} manifest * @param {string} id */ -export async function handle_remote_call_internal(event, options, manifest, id) { +async function handle_remote_call_internal(event, options, manifest, id) { const [hash, name, prerender_args] = id.split('/'); const remotes = manifest._.remotes; @@ -52,6 +52,11 @@ export async function handle_remote_call_internal(event, options, manifest, id) const info = fn.__; const transport = options.hooks.transport; + event.tracing.current.setAttributes({ + 'sveltekit.remote.call.type': info.type, + 'sveltekit.remote.call.name': info.name + }); + /** @type {string[] | undefined} */ let form_client_refreshes; @@ -182,7 +187,9 @@ export async function handle_remote_form_post(event, manifest, id) { }, fn: async (current) => { const traced_event = merge_tracing(event, current); - return with_event(traced_event, () => handle_remote_form_post_internal(event, manifest, id)); + return with_event(traced_event, () => + handle_remote_form_post_internal(traced_event, manifest, id) + ); } }); } From 45d3eaab1908aaa1b7766ea4a7c8eb375f42989a Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Fri, 8 Aug 2025 11:56:13 -0600 Subject: [PATCH 25/74] only load module if exists --- packages/kit/src/exports/vite/dev/index.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 25a5854fec73..48e6b37fc5c7 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -502,9 +502,7 @@ export async function dev(vite, vite_config, svelte_config) { return; } - if (existsSync(tracing.server)) { - await vite.ssrLoadModule(tracing.server); - } + await load_module_if_exists(vite, tracing.server); // we have to import `Server` before calling `set_assets` const { Server } = /** @type {import('types').ServerModule} */ ( @@ -665,3 +663,19 @@ function has_correct_case(file, assets) { return false; } + +/** + * @param {import('vite').ViteDevServer} vite + * @param {string} path + * @returns {Promise} + */ +async function load_module_if_exists(vite, path) { + let extless_path = path; + if (extless_path.endsWith('.js') || extless_path.endsWith('.ts')) { + extless_path = extless_path.slice(-3); + } + + if (existsSync(`${extless_path}.js`) || existsSync(`${extless_path}.ts`)) { + await vite.ssrLoadModule(extless_path); + } +} From cbfaa037adeb71babd91112c2f36672bf9deed71 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Fri, 8 Aug 2025 17:20:30 -0600 Subject: [PATCH 26/74] try this to prevent package issues --- packages/kit/src/exports/hooks/sequence.js | 4 ++-- packages/kit/src/runtime/server/event-state.js | 13 ++++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/kit/src/exports/hooks/sequence.js b/packages/kit/src/exports/hooks/sequence.js index abeac6b74687..4d9b1581777c 100644 --- a/packages/kit/src/exports/hooks/sequence.js +++ b/packages/kit/src/exports/hooks/sequence.js @@ -1,8 +1,8 @@ /** @import { Handle, RequestEvent, ResolveOptions } from '@sveltejs/kit' */ /** @import { MaybePromise } from 'types' */ import { with_event } from '../../runtime/app/server/event.js'; +import { get_event_state } from '../../runtime/server/event-state.js'; import { merge_tracing } from '../../runtime/utils.js'; -import { record_span } from '../../runtime/telemetry/record_span.js'; /** * A helper function for sequencing multiple `handle` calls in a middleware-like manner. @@ -91,7 +91,7 @@ export function sequence(...handlers) { function apply_handle(i, event, parent_options) { const handle = handlers[i]; - return record_span({ + return get_event_state(event).tracing.record_span({ name: 'sveltekit.handle.child', attributes: { 'sveltekit.handle.child.index': i diff --git a/packages/kit/src/runtime/server/event-state.js b/packages/kit/src/runtime/server/event-state.js index 842c6513334c..9ea55b908306 100644 --- a/packages/kit/src/runtime/server/event-state.js +++ b/packages/kit/src/runtime/server/event-state.js @@ -1,6 +1,8 @@ /** @import { RequestEvent } from '@sveltejs/kit' */ /** @import { MaybePromise, PrerenderOptions, ServerHooks, SSROptions, SSRState } from 'types' */ +import { record_span } from '../telemetry/record_span.js'; + export const EVENT_STATE = Symbol('remote'); /** @@ -10,6 +12,9 @@ export const EVENT_STATE = Symbol('remote'); * prerendering: PrerenderOptions | undefined * transport: ServerHooks['transport']; * handleValidationError: ServerHooks['handleValidationError']; + * tracing: { + * record_span: typeof record_span + * } * form_instances?: Map; * remote_data?: Record>; * refreshes?: Record; @@ -25,7 +30,13 @@ export function create_event_state(state, options) { return { prerendering: state.prerendering, transport: options.hooks.transport, - handleValidationError: options.hooks.handleValidationError + handleValidationError: options.hooks.handleValidationError, + // this is necessary to avoid importing `record_span` in `sequence`, which + // won't work because `record_span` depends on `otel`, which depends on + // being bundled through Vite. + tracing: { + record_span + } }; } From 0001ab934c84dd52a64cba4ddc2e328c834c4598 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Fri, 8 Aug 2025 17:25:48 -0600 Subject: [PATCH 27/74] fix: unit tests --- packages/kit/src/exports/hooks/sequence.spec.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/kit/src/exports/hooks/sequence.spec.js b/packages/kit/src/exports/hooks/sequence.spec.js index fe16d5a0bdfb..4f8973f4f5e9 100644 --- a/packages/kit/src/exports/hooks/sequence.spec.js +++ b/packages/kit/src/exports/hooks/sequence.spec.js @@ -1,11 +1,18 @@ import { assert, expect, test } from 'vitest'; import { sequence } from './sequence.js'; import { installPolyfills } from '../node/polyfills.js'; +import { EVENT_STATE } from '../../runtime/server/event-state.js'; installPolyfills(); const dummy_event = /** @type {import('@sveltejs/kit').RequestEvent} */ ({ - tracing: { root: {} } + tracing: { root: {} }, + [EVENT_STATE]: { + tracing: { + // @ts-expect-error + record_span: ({ fn }) => fn() + } + } }); test('applies handlers in sequence', async () => { From 4486b216c6f90bf7a19d75b566635f078414c039 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Fri, 8 Aug 2025 17:32:15 -0600 Subject: [PATCH 28/74] fix again --- packages/kit/src/runtime/server/event-state.js | 6 +++--- packages/kit/src/runtime/server/respond.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/kit/src/runtime/server/event-state.js b/packages/kit/src/runtime/server/event-state.js index 9ea55b908306..770853780899 100644 --- a/packages/kit/src/runtime/server/event-state.js +++ b/packages/kit/src/runtime/server/event-state.js @@ -1,7 +1,6 @@ /** @import { RequestEvent } from '@sveltejs/kit' */ /** @import { MaybePromise, PrerenderOptions, ServerHooks, SSROptions, SSRState } from 'types' */ - -import { record_span } from '../telemetry/record_span.js'; +/** @import { type record_span } from '../telemetry/record_span.js' */ export const EVENT_STATE = Symbol('remote'); @@ -24,9 +23,10 @@ export const EVENT_STATE = Symbol('remote'); /** * @param {SSRState} state * @param {SSROptions} options + * @param {typeof record_span} record_span * @returns {RequestEventState} */ -export function create_event_state(state, options) { +export function create_event_state(state, options, record_span) { return { prerendering: state.prerendering, transport: options.hooks.transport, diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index 54882f3ff37b..b87316992631 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -141,7 +141,7 @@ export async function internal_respond(request, options, manifest, state) { /** @type {import('@sveltejs/kit').RequestEvent} */ const event = { - [EVENT_STATE]: create_event_state(state, options), + [EVENT_STATE]: create_event_state(state, options, record_span), cookies, // @ts-expect-error `fetch` needs to be created after the `event` itself fetch: null, From 30ffc686e76880f5ba11d4911e186158ff00a4de Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Mon, 11 Aug 2025 15:39:30 -0600 Subject: [PATCH 29/74] move event.js to internal --- packages/kit/src/exports/hooks/sequence.js | 2 +- .../app/server => exports/internal}/event.js | 2 +- packages/kit/src/exports/internal/index.js | 2 ++ packages/kit/src/runtime/app/server/index.js | 2 +- .../src/runtime/app/server/remote/command.js | 2 +- .../kit/src/runtime/app/server/remote/form.js | 2 +- .../runtime/app/server/remote/prerender.js | 2 +- .../src/runtime/app/server/remote/query.js | 2 +- .../src/runtime/app/server/remote/shared.js | 2 +- packages/kit/src/runtime/server/endpoint.js | 3 +-- .../kit/src/runtime/server/page/actions.js | 9 ++++++-- .../kit/src/runtime/server/page/load_data.js | 2 +- .../kit/src/runtime/server/page/render.js | 2 +- packages/kit/src/runtime/server/remote.js | 3 +-- packages/kit/src/runtime/server/respond.js | 3 +-- packages/kit/src/runtime/server/utils.js | 2 +- packages/kit/types/index.d.ts | 22 +++++++++---------- 17 files changed, 34 insertions(+), 30 deletions(-) rename packages/kit/src/{runtime/app/server => exports/internal}/event.js (98%) diff --git a/packages/kit/src/exports/hooks/sequence.js b/packages/kit/src/exports/hooks/sequence.js index 4d9b1581777c..4d6d81d2b16b 100644 --- a/packages/kit/src/exports/hooks/sequence.js +++ b/packages/kit/src/exports/hooks/sequence.js @@ -1,6 +1,6 @@ /** @import { Handle, RequestEvent, ResolveOptions } from '@sveltejs/kit' */ /** @import { MaybePromise } from 'types' */ -import { with_event } from '../../runtime/app/server/event.js'; +import { with_event } from '@sveltejs/kit/internal'; import { get_event_state } from '../../runtime/server/event-state.js'; import { merge_tracing } from '../../runtime/utils.js'; diff --git a/packages/kit/src/runtime/app/server/event.js b/packages/kit/src/exports/internal/event.js similarity index 98% rename from packages/kit/src/runtime/app/server/event.js rename to packages/kit/src/exports/internal/event.js index 8351e21e9000..dc3c2a04da6e 100644 --- a/packages/kit/src/runtime/app/server/event.js +++ b/packages/kit/src/exports/internal/event.js @@ -3,7 +3,7 @@ /** @type {RequestEvent | null} */ let request_event = null; -/** @type {import('node:async_hooks').AsyncLocalStorage} */ +/** @type {import('node:async_hooks').AsyncLocalStorage | null} */ let als; import('node:async_hooks') diff --git a/packages/kit/src/exports/internal/index.js b/packages/kit/src/exports/internal/index.js index c358bca93251..7b0e7bb107e0 100644 --- a/packages/kit/src/exports/internal/index.js +++ b/packages/kit/src/exports/internal/index.js @@ -62,4 +62,6 @@ export class ActionFailure { } } +export { with_event, getRequestEvent } from './event.js'; + export { validate_remote_functions } from './remote-functions.js'; diff --git a/packages/kit/src/runtime/app/server/index.js b/packages/kit/src/runtime/app/server/index.js index 3c517b8b1cde..790f78dbba60 100644 --- a/packages/kit/src/runtime/app/server/index.js +++ b/packages/kit/src/runtime/app/server/index.js @@ -72,6 +72,6 @@ export function read(asset) { throw new Error(`Asset does not exist: ${file}`); } -export { getRequestEvent } from './event.js'; +export { getRequestEvent } from '@sveltejs/kit/internal'; export { query, prerender, command, form } from './remote/index.js'; diff --git a/packages/kit/src/runtime/app/server/remote/command.js b/packages/kit/src/runtime/app/server/remote/command.js index 951ab3ab6ff8..4894ed97d1cd 100644 --- a/packages/kit/src/runtime/app/server/remote/command.js +++ b/packages/kit/src/runtime/app/server/remote/command.js @@ -1,7 +1,7 @@ /** @import { RemoteCommand } from '@sveltejs/kit' */ /** @import { RemoteInfo, MaybePromise } from 'types' */ /** @import { StandardSchemaV1 } from '@standard-schema/spec' */ -import { getRequestEvent } from '../event.js'; +import { getRequestEvent } from '@sveltejs/kit/internal'; import { check_experimental, create_validator, run_remote_function } from './shared.js'; import { get_event_state } from '../../../server/event-state.js'; diff --git a/packages/kit/src/runtime/app/server/remote/form.js b/packages/kit/src/runtime/app/server/remote/form.js index 0f5571820ee9..73153c4f0608 100644 --- a/packages/kit/src/runtime/app/server/remote/form.js +++ b/packages/kit/src/runtime/app/server/remote/form.js @@ -1,6 +1,6 @@ /** @import { RemoteForm } from '@sveltejs/kit' */ /** @import { RemoteInfo, MaybePromise } from 'types' */ -import { getRequestEvent } from '../event.js'; +import { getRequestEvent } from '@sveltejs/kit/internal'; import { check_experimental, run_remote_function } from './shared.js'; import { get_event_state } from '../../../server/event-state.js'; diff --git a/packages/kit/src/runtime/app/server/remote/prerender.js b/packages/kit/src/runtime/app/server/remote/prerender.js index ea4a3a909fb2..7cb99a5d5a32 100644 --- a/packages/kit/src/runtime/app/server/remote/prerender.js +++ b/packages/kit/src/runtime/app/server/remote/prerender.js @@ -3,7 +3,7 @@ /** @import { StandardSchemaV1 } from '@standard-schema/spec' */ import { error, json } from '@sveltejs/kit'; import { DEV } from 'esm-env'; -import { getRequestEvent } from '../event.js'; +import { getRequestEvent } from '@sveltejs/kit/internal'; import { create_remote_cache_key, stringify, stringify_remote_arg } from '../../../shared.js'; import { app_dir, base } from '__sveltekit/paths'; import { diff --git a/packages/kit/src/runtime/app/server/remote/query.js b/packages/kit/src/runtime/app/server/remote/query.js index 270e9f3340f8..babf224528ca 100644 --- a/packages/kit/src/runtime/app/server/remote/query.js +++ b/packages/kit/src/runtime/app/server/remote/query.js @@ -1,7 +1,7 @@ /** @import { RemoteQuery, RemoteQueryFunction } from '@sveltejs/kit' */ /** @import { RemoteInfo, MaybePromise } from 'types' */ /** @import { StandardSchemaV1 } from '@standard-schema/spec' */ -import { getRequestEvent } from '../event.js'; +import { getRequestEvent } from '@sveltejs/kit/internal'; import { create_remote_cache_key, stringify_remote_arg } from '../../../shared.js'; import { prerendering } from '__sveltekit/environment'; import { diff --git a/packages/kit/src/runtime/app/server/remote/shared.js b/packages/kit/src/runtime/app/server/remote/shared.js index 5ad8b433ae86..8a498311b9ff 100644 --- a/packages/kit/src/runtime/app/server/remote/shared.js +++ b/packages/kit/src/runtime/app/server/remote/shared.js @@ -2,7 +2,7 @@ /** @import { ServerHooks, MaybePromise } from 'types' */ import { parse } from 'devalue'; import { error } from '@sveltejs/kit'; -import { getRequestEvent, with_event } from '../event.js'; +import { getRequestEvent, with_event } from '@sveltejs/kit/internal'; import { create_remote_cache_key, stringify_remote_arg } from '../../../shared.js'; import { EVENT_STATE, get_event_state } from '../../../server/event-state.js'; diff --git a/packages/kit/src/runtime/server/endpoint.js b/packages/kit/src/runtime/server/endpoint.js index a88a9f4c5a70..eca20aabcaa0 100644 --- a/packages/kit/src/runtime/server/endpoint.js +++ b/packages/kit/src/runtime/server/endpoint.js @@ -1,7 +1,6 @@ -import { Redirect } from '@sveltejs/kit/internal'; +import { Redirect, with_event } from '@sveltejs/kit/internal'; import { ENDPOINT_METHODS, PAGE_METHODS } from '../../constants.js'; import { negotiate } from '../../utils/http.js'; -import { with_event } from '../app/server/event.js'; import { method_not_allowed } from './utils.js'; /** diff --git a/packages/kit/src/runtime/server/page/actions.js b/packages/kit/src/runtime/server/page/actions.js index 391e5cffaf46..18007ec433e0 100644 --- a/packages/kit/src/runtime/server/page/actions.js +++ b/packages/kit/src/runtime/server/page/actions.js @@ -3,11 +3,16 @@ import * as devalue from 'devalue'; import { DEV } from 'esm-env'; import { json } from '@sveltejs/kit'; -import { HttpError, Redirect, ActionFailure, SvelteKitError } from '@sveltejs/kit/internal'; +import { + HttpError, + Redirect, + ActionFailure, + SvelteKitError, + with_event +} from '@sveltejs/kit/internal'; import { get_status, normalize_error } from '../../../utils/error.js'; import { is_form_content_type, negotiate } from '../../../utils/http.js'; import { handle_error_and_jsonify } from '../utils.js'; -import { with_event } from '../../app/server/event.js'; import { record_span } from '../../telemetry/record_span.js'; import { merge_tracing } from '../../utils.js'; diff --git a/packages/kit/src/runtime/server/page/load_data.js b/packages/kit/src/runtime/server/page/load_data.js index ba1c6d0846cd..405d8f1facf5 100644 --- a/packages/kit/src/runtime/server/page/load_data.js +++ b/packages/kit/src/runtime/server/page/load_data.js @@ -2,7 +2,7 @@ import { DEV } from 'esm-env'; import { disable_search, make_trackable } from '../../../utils/url.js'; import { validate_depends, validate_load_response } from '../../shared.js'; import { b64_encode, merge_tracing } from '../../utils.js'; -import { with_event } from '../../app/server/event.js'; +import { with_event } from '@sveltejs/kit/internal'; import { record_span } from '../../telemetry/record_span.js'; import { get_node_type } from '../utils.js'; diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index 50e1ad057ae5..362f4a981bc6 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -15,7 +15,7 @@ import { SVELTE_KIT_ASSETS } from '../../../constants.js'; import { SCHEME } from '../../../utils/url.js'; import { create_server_routing_response, generate_route_object } from './server_routing.js'; import { add_resolution_suffix } from '../../pathname.js'; -import { with_event } from '../../app/server/event.js'; +import { with_event } from '@sveltejs/kit/internal'; import { get_event_state } from '../event-state.js'; // TODO rename this function/module diff --git a/packages/kit/src/runtime/server/remote.js b/packages/kit/src/runtime/server/remote.js index 77eb14813109..d0cea37d6e77 100644 --- a/packages/kit/src/runtime/server/remote.js +++ b/packages/kit/src/runtime/server/remote.js @@ -2,9 +2,8 @@ /** @import { RemoteFunctionResponse, RemoteInfo, SSROptions } from 'types' */ import { json, error } from '@sveltejs/kit'; -import { HttpError, Redirect, SvelteKitError } from '@sveltejs/kit/internal'; +import { HttpError, Redirect, SvelteKitError, with_event } from '@sveltejs/kit/internal'; import { app_dir, base } from '__sveltekit/paths'; -import { with_event } from '../app/server/event.js'; import { is_form_content_type } from '../../utils/http.js'; import { parse_remote_arg, stringify } from '../shared.js'; import { handle_error_and_jsonify } from './utils.js'; diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index b87316992631..d32cf16647dc 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -1,6 +1,6 @@ import { DEV } from 'esm-env'; import { json, text } from '@sveltejs/kit'; -import { Redirect, SvelteKitError } from '@sveltejs/kit/internal'; +import { Redirect, SvelteKitError, with_event } from '@sveltejs/kit/internal'; import { base, app_dir } from '__sveltekit/paths'; import { is_endpoint_request, render_endpoint } from './endpoint.js'; import { render_page } from './page/index.js'; @@ -34,7 +34,6 @@ import { strip_resolution_suffix } from '../pathname.js'; import { get_remote_id, handle_remote_call } from './remote.js'; -import { with_event } from '../app/server/event.js'; import { record_span } from '../telemetry/record_span.js'; import { merge_tracing } from '../utils.js'; import { create_event_state, EVENT_STATE } from './event-state.js'; diff --git a/packages/kit/src/runtime/server/utils.js b/packages/kit/src/runtime/server/utils.js index 92ef239bf3e3..c9a05bcb2de8 100644 --- a/packages/kit/src/runtime/server/utils.js +++ b/packages/kit/src/runtime/server/utils.js @@ -6,7 +6,7 @@ import { negotiate } from '../../utils/http.js'; import { fix_stack_trace } from '../shared-server.js'; import { ENDPOINT_METHODS } from '../../constants.js'; import { escape_html } from '../../utils/escape.js'; -import { with_event } from '../app/server/event.js'; +import { with_event } from '../../exports/internal/event.js'; /** @param {any} body */ export function is_pojo(body) { diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 2d40662c4328..13c9b130bab6 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -4,7 +4,7 @@ declare module '@sveltejs/kit' { import type { SvelteConfig } from '@sveltejs/vite-plugin-svelte'; import type { StandardSchemaV1 } from '@standard-schema/spec'; - import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams, ResolvedPathname } from '$app/types'; + import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams_1, ResolvedPathname } from '$app/types'; import type { Span } from '@opentelemetry/api'; /** * [Adapters](https://svelte.dev/docs/kit/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. @@ -873,7 +873,7 @@ declare module '@sveltejs/kit' { * rather than using `Load` directly. */ export type Load< - Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, + Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, InputData extends Record | null = Record | null, ParentData extends Record = Record, OutputData extends Record | void = Record | void, @@ -885,7 +885,7 @@ declare module '@sveltejs/kit' { * rather than using `LoadEvent` directly. */ export interface LoadEvent< - Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, + Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, Data extends Record | null = Record | null, ParentData extends Record = Record, RouteId extends AppRouteId | null = AppRouteId | null @@ -1006,7 +1006,7 @@ declare module '@sveltejs/kit' { } export interface NavigationEvent< - Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, + Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, RouteId extends AppRouteId | null = AppRouteId | null > { /** @@ -1146,7 +1146,7 @@ declare module '@sveltejs/kit' { * The shape of the [`page`](https://svelte.dev/docs/kit/$app-state#page) reactive object and the [`$page`](https://svelte.dev/docs/kit/$app-stores) store. */ export interface Page< - Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, + Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, RouteId extends AppRouteId | null = AppRouteId | null > { /** @@ -1194,7 +1194,7 @@ declare module '@sveltejs/kit' { export type ParamMatcher = (param: string) => boolean; export interface RequestEvent< - Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, + Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, RouteId extends AppRouteId | null = AppRouteId | null > { /** @@ -1305,7 +1305,7 @@ declare module '@sveltejs/kit' { * It receives `Params` as the first generic argument, which you can skip by using [generated types](https://svelte.dev/docs/kit/types#Generated-types) instead. */ export type RequestHandler< - Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, + Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, RouteId extends AppRouteId | null = AppRouteId | null > = (event: RequestEvent) => MaybePromise; @@ -1386,14 +1386,14 @@ declare module '@sveltejs/kit' { * rather than using `ServerLoad` directly. */ export type ServerLoad< - Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, + Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, ParentData extends Record = Record, OutputData extends Record | void = Record | void, RouteId extends AppRouteId | null = AppRouteId | null > = (event: ServerLoadEvent) => MaybePromise; export interface ServerLoadEvent< - Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, + Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, ParentData extends Record = Record, RouteId extends AppRouteId | null = AppRouteId | null > extends RequestEvent { @@ -1475,7 +1475,7 @@ declare module '@sveltejs/kit' { * See [form actions](https://svelte.dev/docs/kit/form-actions) for more information. */ export type Action< - Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, + Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, OutputData extends Record | void = Record | void, RouteId extends AppRouteId | null = AppRouteId | null > = (event: RequestEvent) => MaybePromise; @@ -1485,7 +1485,7 @@ declare module '@sveltejs/kit' { * See [form actions](https://svelte.dev/docs/kit/form-actions) for more information. */ export type Actions< - Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, + Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, OutputData extends Record | void = Record | void, RouteId extends AppRouteId | null = AppRouteId | null > = Record>; From b5268319f7307d01870315a21fe9ee0f710a527f Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Mon, 11 Aug 2025 16:07:54 -0600 Subject: [PATCH 30/74] move event-state to internal --- packages/kit/src/exports/hooks/sequence.js | 4 +--- .../kit/src/exports/hooks/sequence.spec.js | 20 ++++++++++--------- .../internal}/event-state.js | 7 +++---- packages/kit/src/exports/internal/index.js | 18 +++++++++++++++++ .../src/runtime/app/server/remote/command.js | 3 +-- .../kit/src/runtime/app/server/remote/form.js | 3 +-- .../runtime/app/server/remote/prerender.js | 3 +-- .../src/runtime/app/server/remote/query.js | 3 +-- .../src/runtime/app/server/remote/shared.js | 3 +-- .../kit/src/runtime/server/page/actions.js | 4 ++-- .../kit/src/runtime/server/page/load_data.js | 4 ++-- .../kit/src/runtime/server/page/render.js | 3 +-- packages/kit/src/runtime/server/remote.js | 11 +++++++--- packages/kit/src/runtime/server/respond.js | 11 +++++++--- .../kit/src/runtime/telemetry/record_span.js | 11 ++-------- packages/kit/src/runtime/utils.js | 16 --------------- packages/kit/src/types/internal.d.ts | 7 +++++++ 17 files changed, 68 insertions(+), 63 deletions(-) rename packages/kit/src/{runtime/server => exports/internal}/event-state.js (88%) diff --git a/packages/kit/src/exports/hooks/sequence.js b/packages/kit/src/exports/hooks/sequence.js index 4d6d81d2b16b..99ad93e42586 100644 --- a/packages/kit/src/exports/hooks/sequence.js +++ b/packages/kit/src/exports/hooks/sequence.js @@ -1,8 +1,6 @@ /** @import { Handle, RequestEvent, ResolveOptions } from '@sveltejs/kit' */ /** @import { MaybePromise } from 'types' */ -import { with_event } from '@sveltejs/kit/internal'; -import { get_event_state } from '../../runtime/server/event-state.js'; -import { merge_tracing } from '../../runtime/utils.js'; +import { with_event, get_event_state, merge_tracing } from '@sveltejs/kit/internal'; /** * A helper function for sequencing multiple `handle` calls in a middleware-like manner. diff --git a/packages/kit/src/exports/hooks/sequence.spec.js b/packages/kit/src/exports/hooks/sequence.spec.js index 4f8973f4f5e9..800d6dc1b8e8 100644 --- a/packages/kit/src/exports/hooks/sequence.spec.js +++ b/packages/kit/src/exports/hooks/sequence.spec.js @@ -1,19 +1,21 @@ import { assert, expect, test } from 'vitest'; import { sequence } from './sequence.js'; import { installPolyfills } from '../node/polyfills.js'; -import { EVENT_STATE } from '../../runtime/server/event-state.js'; +import { EVENT_STATE } from '@sveltejs/kit/internal'; installPolyfills(); -const dummy_event = /** @type {import('@sveltejs/kit').RequestEvent} */ ({ - tracing: { root: {} }, - [EVENT_STATE]: { - tracing: { - // @ts-expect-error - record_span: ({ fn }) => fn() +const dummy_event = /** @type {import('@sveltejs/kit').RequestEvent} */ ( + /** @type {unknown} */ ({ + tracing: { root: {} }, + [EVENT_STATE]: { + tracing: { + // @ts-expect-error + record_span: ({ fn }) => fn() + } } - } -}); + }) +); test('applies handlers in sequence', async () => { /** @type {string[]} */ diff --git a/packages/kit/src/runtime/server/event-state.js b/packages/kit/src/exports/internal/event-state.js similarity index 88% rename from packages/kit/src/runtime/server/event-state.js rename to packages/kit/src/exports/internal/event-state.js index 770853780899..fd1166ea0dba 100644 --- a/packages/kit/src/runtime/server/event-state.js +++ b/packages/kit/src/exports/internal/event-state.js @@ -1,6 +1,5 @@ /** @import { RequestEvent } from '@sveltejs/kit' */ -/** @import { MaybePromise, PrerenderOptions, ServerHooks, SSROptions, SSRState } from 'types' */ -/** @import { type record_span } from '../telemetry/record_span.js' */ +/** @import { MaybePromise, PrerenderOptions, ServerHooks, SSROptions, SSRState, RecordSpan } from 'types' */ export const EVENT_STATE = Symbol('remote'); @@ -12,7 +11,7 @@ export const EVENT_STATE = Symbol('remote'); * transport: ServerHooks['transport']; * handleValidationError: ServerHooks['handleValidationError']; * tracing: { - * record_span: typeof record_span + * record_span: RecordSpan * } * form_instances?: Map; * remote_data?: Record>; @@ -23,7 +22,7 @@ export const EVENT_STATE = Symbol('remote'); /** * @param {SSRState} state * @param {SSROptions} options - * @param {typeof record_span} record_span + * @param {RecordSpan} record_span * @returns {RequestEventState} */ export function create_event_state(state, options, record_span) { diff --git a/packages/kit/src/exports/internal/index.js b/packages/kit/src/exports/internal/index.js index 7b0e7bb107e0..ada44b6cb821 100644 --- a/packages/kit/src/exports/internal/index.js +++ b/packages/kit/src/exports/internal/index.js @@ -64,4 +64,22 @@ export class ActionFailure { export { with_event, getRequestEvent } from './event.js'; +export { EVENT_STATE, get_event_state, create_event_state } from './event-state.js'; + export { validate_remote_functions } from './remote-functions.js'; + +/** + * @template {{ tracing: { enabled: boolean, root: import('@opentelemetry/api').Span, current: import('@opentelemetry/api').Span } }} T + * @param {T} event_like + * @param {import('@opentelemetry/api').Span} current + * @returns {T} + */ +export function merge_tracing(event_like, current) { + return { + ...event_like, + tracing: { + ...event_like.tracing, + current + } + }; +} diff --git a/packages/kit/src/runtime/app/server/remote/command.js b/packages/kit/src/runtime/app/server/remote/command.js index 4894ed97d1cd..726cf9de2f53 100644 --- a/packages/kit/src/runtime/app/server/remote/command.js +++ b/packages/kit/src/runtime/app/server/remote/command.js @@ -1,9 +1,8 @@ /** @import { RemoteCommand } from '@sveltejs/kit' */ /** @import { RemoteInfo, MaybePromise } from 'types' */ /** @import { StandardSchemaV1 } from '@standard-schema/spec' */ -import { getRequestEvent } from '@sveltejs/kit/internal'; +import { getRequestEvent, get_event_state } from '@sveltejs/kit/internal'; import { check_experimental, create_validator, run_remote_function } from './shared.js'; -import { get_event_state } from '../../../server/event-state.js'; /** * Creates a remote command. When called from the browser, the function will be invoked on the server via a `fetch` call. diff --git a/packages/kit/src/runtime/app/server/remote/form.js b/packages/kit/src/runtime/app/server/remote/form.js index 73153c4f0608..ca1b31101fad 100644 --- a/packages/kit/src/runtime/app/server/remote/form.js +++ b/packages/kit/src/runtime/app/server/remote/form.js @@ -1,8 +1,7 @@ /** @import { RemoteForm } from '@sveltejs/kit' */ /** @import { RemoteInfo, MaybePromise } from 'types' */ -import { getRequestEvent } from '@sveltejs/kit/internal'; +import { getRequestEvent, get_event_state } from '@sveltejs/kit/internal'; import { check_experimental, run_remote_function } from './shared.js'; -import { get_event_state } from '../../../server/event-state.js'; /** * Creates a form object that can be spread onto a `
` element. diff --git a/packages/kit/src/runtime/app/server/remote/prerender.js b/packages/kit/src/runtime/app/server/remote/prerender.js index 7cb99a5d5a32..5de0a936b907 100644 --- a/packages/kit/src/runtime/app/server/remote/prerender.js +++ b/packages/kit/src/runtime/app/server/remote/prerender.js @@ -3,7 +3,7 @@ /** @import { StandardSchemaV1 } from '@standard-schema/spec' */ import { error, json } from '@sveltejs/kit'; import { DEV } from 'esm-env'; -import { getRequestEvent } from '@sveltejs/kit/internal'; +import { getRequestEvent, get_event_state } from '@sveltejs/kit/internal'; import { create_remote_cache_key, stringify, stringify_remote_arg } from '../../../shared.js'; import { app_dir, base } from '__sveltekit/paths'; import { @@ -13,7 +13,6 @@ import { parse_remote_response, run_remote_function } from './shared.js'; -import { get_event_state } from '../../../server/event-state.js'; /** * Creates a remote prerender function. When called from the browser, the function will be invoked on the server via a `fetch` call. diff --git a/packages/kit/src/runtime/app/server/remote/query.js b/packages/kit/src/runtime/app/server/remote/query.js index babf224528ca..2d77cb8e20a0 100644 --- a/packages/kit/src/runtime/app/server/remote/query.js +++ b/packages/kit/src/runtime/app/server/remote/query.js @@ -1,7 +1,7 @@ /** @import { RemoteQuery, RemoteQueryFunction } from '@sveltejs/kit' */ /** @import { RemoteInfo, MaybePromise } from 'types' */ /** @import { StandardSchemaV1 } from '@standard-schema/spec' */ -import { getRequestEvent } from '@sveltejs/kit/internal'; +import { getRequestEvent, get_event_state } from '@sveltejs/kit/internal'; import { create_remote_cache_key, stringify_remote_arg } from '../../../shared.js'; import { prerendering } from '__sveltekit/environment'; import { @@ -10,7 +10,6 @@ import { get_response, run_remote_function } from './shared.js'; -import { get_event_state } from '../../../server/event-state.js'; /** * Creates a remote query. When called from the browser, the function will be invoked on the server via a `fetch` call. diff --git a/packages/kit/src/runtime/app/server/remote/shared.js b/packages/kit/src/runtime/app/server/remote/shared.js index 8a498311b9ff..3b188fd98df6 100644 --- a/packages/kit/src/runtime/app/server/remote/shared.js +++ b/packages/kit/src/runtime/app/server/remote/shared.js @@ -2,9 +2,8 @@ /** @import { ServerHooks, MaybePromise } from 'types' */ import { parse } from 'devalue'; import { error } from '@sveltejs/kit'; -import { getRequestEvent, with_event } from '@sveltejs/kit/internal'; +import { getRequestEvent, with_event, EVENT_STATE, get_event_state } from '@sveltejs/kit/internal'; import { create_remote_cache_key, stringify_remote_arg } from '../../../shared.js'; -import { EVENT_STATE, get_event_state } from '../../../server/event-state.js'; /** * @param {any} validate_or_fn diff --git a/packages/kit/src/runtime/server/page/actions.js b/packages/kit/src/runtime/server/page/actions.js index 18007ec433e0..3d607ffed55f 100644 --- a/packages/kit/src/runtime/server/page/actions.js +++ b/packages/kit/src/runtime/server/page/actions.js @@ -8,13 +8,13 @@ import { Redirect, ActionFailure, SvelteKitError, - with_event + with_event, + merge_tracing } from '@sveltejs/kit/internal'; import { get_status, normalize_error } from '../../../utils/error.js'; import { is_form_content_type, negotiate } from '../../../utils/http.js'; import { handle_error_and_jsonify } from '../utils.js'; import { record_span } from '../../telemetry/record_span.js'; -import { merge_tracing } from '../../utils.js'; /** @param {RequestEvent} event */ export function is_action_json_request(event) { diff --git a/packages/kit/src/runtime/server/page/load_data.js b/packages/kit/src/runtime/server/page/load_data.js index 405d8f1facf5..50a1794ddd74 100644 --- a/packages/kit/src/runtime/server/page/load_data.js +++ b/packages/kit/src/runtime/server/page/load_data.js @@ -1,8 +1,8 @@ import { DEV } from 'esm-env'; import { disable_search, make_trackable } from '../../../utils/url.js'; import { validate_depends, validate_load_response } from '../../shared.js'; -import { b64_encode, merge_tracing } from '../../utils.js'; -import { with_event } from '@sveltejs/kit/internal'; +import { b64_encode } from '../../utils.js'; +import { with_event, merge_tracing } from '@sveltejs/kit/internal'; import { record_span } from '../../telemetry/record_span.js'; import { get_node_type } from '../utils.js'; diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index 362f4a981bc6..3d7e59fd8f67 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -15,8 +15,7 @@ import { SVELTE_KIT_ASSETS } from '../../../constants.js'; import { SCHEME } from '../../../utils/url.js'; import { create_server_routing_response, generate_route_object } from './server_routing.js'; import { add_resolution_suffix } from '../../pathname.js'; -import { with_event } from '@sveltejs/kit/internal'; -import { get_event_state } from '../event-state.js'; +import { with_event, get_event_state } from '@sveltejs/kit/internal'; // TODO rename this function/module diff --git a/packages/kit/src/runtime/server/remote.js b/packages/kit/src/runtime/server/remote.js index d0cea37d6e77..01992eb505fc 100644 --- a/packages/kit/src/runtime/server/remote.js +++ b/packages/kit/src/runtime/server/remote.js @@ -2,7 +2,14 @@ /** @import { RemoteFunctionResponse, RemoteInfo, SSROptions } from 'types' */ import { json, error } from '@sveltejs/kit'; -import { HttpError, Redirect, SvelteKitError, with_event } from '@sveltejs/kit/internal'; +import { + HttpError, + Redirect, + SvelteKitError, + with_event, + get_event_state, + merge_tracing +} from '@sveltejs/kit/internal'; import { app_dir, base } from '__sveltekit/paths'; import { is_form_content_type } from '../../utils/http.js'; import { parse_remote_arg, stringify } from '../shared.js'; @@ -10,9 +17,7 @@ import { handle_error_and_jsonify } from './utils.js'; import { normalize_error } from '../../utils/error.js'; import { check_incorrect_fail_use } from './page/actions.js'; import { DEV } from 'esm-env'; -import { get_event_state } from './event-state.js'; import { record_span } from '../telemetry/record_span.js'; -import { merge_tracing } from '../utils.js'; /** @type {typeof handle_remote_call_internal} */ export async function handle_remote_call(event, options, manifest, id) { diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index d32cf16647dc..94b066463ffa 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -1,6 +1,13 @@ import { DEV } from 'esm-env'; import { json, text } from '@sveltejs/kit'; -import { Redirect, SvelteKitError, with_event } from '@sveltejs/kit/internal'; +import { + Redirect, + SvelteKitError, + with_event, + create_event_state, + EVENT_STATE, + merge_tracing +} from '@sveltejs/kit/internal'; import { base, app_dir } from '__sveltekit/paths'; import { is_endpoint_request, render_endpoint } from './endpoint.js'; import { render_page } from './page/index.js'; @@ -35,8 +42,6 @@ import { } from '../pathname.js'; import { get_remote_id, handle_remote_call } from './remote.js'; import { record_span } from '../telemetry/record_span.js'; -import { merge_tracing } from '../utils.js'; -import { create_event_state, EVENT_STATE } from './event-state.js'; import { otel } from '../telemetry/otel.js'; /* global __SVELTEKIT_ADAPTER_NAME__ */ diff --git a/packages/kit/src/runtime/telemetry/record_span.js b/packages/kit/src/runtime/telemetry/record_span.js index 1bc3fcb6dfed..eaabb1ea5e4c 100644 --- a/packages/kit/src/runtime/telemetry/record_span.js +++ b/packages/kit/src/runtime/telemetry/record_span.js @@ -1,16 +1,9 @@ -/** @import { Attributes, Span } from '@opentelemetry/api' */ +/** @import { RecordSpan } from 'types' */ import { HttpError, Redirect } from '@sveltejs/kit/internal'; import { noop_span } from './noop.js'; import { otel } from './otel.js'; -/** - * @template T - * @param {Object} options - * @param {string} options.name - * @param {Attributes} options.attributes - * @param {function(Span): Promise} options.fn - * @returns {Promise} - */ +/** @type {RecordSpan} */ export async function record_span({ name, attributes, fn }) { if (otel === null) { return fn(noop_span); diff --git a/packages/kit/src/runtime/utils.js b/packages/kit/src/runtime/utils.js index d8893919435e..2da4498d9b7f 100644 --- a/packages/kit/src/runtime/utils.js +++ b/packages/kit/src/runtime/utils.js @@ -53,19 +53,3 @@ export function get_relative_path(from, to) { return from_parts.concat(to_parts).join('/'); } - -/** - * @template {{ tracing: { enabled: boolean, root: import('@opentelemetry/api').Span, current: import('@opentelemetry/api').Span } }} T - * @param {T} event_like - * @param {import('@opentelemetry/api').Span} current - * @returns {T} - */ -export function merge_tracing(event_like, current) { - return { - ...event_like, - tracing: { - ...event_like.tracing, - current - } - }; -} diff --git a/packages/kit/src/types/internal.d.ts b/packages/kit/src/types/internal.d.ts index 2f9c7aad7abd..f51737fe4ada 100644 --- a/packages/kit/src/types/internal.d.ts +++ b/packages/kit/src/types/internal.d.ts @@ -30,6 +30,7 @@ import { RequestOptions, TrailingSlash } from './private.js'; +import { Span } from '@opentelemetry/api'; export interface ServerModule { Server: typeof InternalServer; @@ -566,5 +567,11 @@ export type RemoteInfo = inputs?: RemotePrerenderInputsGenerator; }; +export type RecordSpan = (options: { + name: string; + attributes: Record; + fn: (current: Span) => Promise; +}) => Promise; + export * from '../exports/index.js'; export * from './private.js'; From 5954ae4aacac2b587effd07ed20288fb10d8c3b3 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Mon, 11 Aug 2025 17:07:57 -0600 Subject: [PATCH 31/74] changeset and docs --- .changeset/early-taxis-make.md | 2 +- .changeset/whole-bananas-sort.md | 9 +++ .../30-project-structure.md | 4 +- .../docs/30-advanced/68-observability.md | 62 +++++++++++++++++++ 4 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 .changeset/whole-bananas-sort.md create mode 100644 documentation/docs/30-advanced/68-observability.md diff --git a/.changeset/early-taxis-make.md b/.changeset/early-taxis-make.md index c21656024abc..4508252ef88b 100644 --- a/.changeset/early-taxis-make.md +++ b/.changeset/early-taxis-make.md @@ -2,4 +2,4 @@ '@sveltejs/kit': minor --- -feat: OpenTelemetry tracing for `handle`, `sequence`, form actions, and `load` functions running on the server +feat: OpenTelemetry tracing for `handle`, `sequence`, form actions, remote functions, and `load` functions running on the server diff --git a/.changeset/whole-bananas-sort.md b/.changeset/whole-bananas-sort.md new file mode 100644 index 000000000000..e3aca360ce43 --- /dev/null +++ b/.changeset/whole-bananas-sort.md @@ -0,0 +1,9 @@ +--- +'@sveltejs/adapter-cloudflare': minor +'@sveltejs/adapter-netlify': minor +'@sveltejs/adapter-vercel': minor +'@sveltejs/adapter-node': minor +'@sveltejs/kit': minor +--- + +feat: add `tracing.server.ts` for tracing instrumentation and setup diff --git a/documentation/docs/10-getting-started/30-project-structure.md b/documentation/docs/10-getting-started/30-project-structure.md index 64bae0a695c1..773a730f2c3b 100644 --- a/documentation/docs/10-getting-started/30-project-structure.md +++ b/documentation/docs/10-getting-started/30-project-structure.md @@ -19,7 +19,8 @@ my-project/ │ ├ error.html │ ├ hooks.client.js │ ├ hooks.server.js -│ └ service-worker.js +| ├ service-worker.js +│ └ tracing.server.js ├ static/ │ └ [your static assets] ├ tests/ @@ -54,6 +55,7 @@ The `src` directory contains the meat of your project. Everything except `src/ro - `hooks.client.js` contains your client [hooks](hooks) - `hooks.server.js` contains your server [hooks](hooks) - `service-worker.js` contains your [service worker](service-workers) +- `tracing.server.js` contains your [tracing](observability) setup and instrumentation code (Whether the project contains `.js` or `.ts` files depends on whether you opt to use TypeScript when you create your project.) diff --git a/documentation/docs/30-advanced/68-observability.md b/documentation/docs/30-advanced/68-observability.md new file mode 100644 index 000000000000..b6ff18d68e10 --- /dev/null +++ b/documentation/docs/30-advanced/68-observability.md @@ -0,0 +1,62 @@ +--- +title: Observability +--- + +
+

Available since 2.28

+
+ +> [!NOTE] This feature is experimental. Expect bugs and breaking changes in minor versions (though we'll do our best to keep those to an absolute minimum). Please provide feedback! + +Sometimes, you may need to observe how your application is behaving in order to improve performance or find the root cause of a pesky bug. To help with this, SvelteKit can emit serverside [OpenTelemetry](https://opentelemetry.io) spans for the following: + +- `handle` +- `sequence` (`sequence`d `handle` functions will show up as children of each other and the root handle hook) +- `load` (includes univeral `load`s when they're run on the server) +- Form actions +- Remote Functions + +To enable these spans, add the following to your `svelte.config.js`'s `kit` configuration: + +```ts +{ + experimental: { + tracing: { + server: true + } + } +} +``` + +Just telling SvelteKit to emit spans won't get you far, though -- you need to actually collect them somewhere to be able to view them. SvelteKit provides `src/tracing.server.ts` as a place to write your tracing setup and instrumentation code. It's guaranteed to be run prior to your application code being imported. + +> [!NOTE] Tracing -- and more significantly, tracing instrumentation -- can have a nontrivial overhead. Before you go all-in on tracing, consider whether or not you really need it, or if it might be more appropriate to turn it on in development and preview environments only. + +## Development Quickstart + +To view your first trace, you'll need to set up a local collector. We recommend [Jaeger](https://www.jaegertracing.io/docs/2.7/getting-started/), as they provide an easy-to-use quickstart command. Once your collector is running locally: + +- Turn on the experemental flag from above in your `svelte.config.js` +- Use your package manager to install `@opentelemetry/sdk-node`, `opentelemetry/auto-instrumentations-node`, `@opentelemetry/exporter-trace-otlp-proto`, and `import-in-the-middle` +- Create `src/tracing.server.ts` with the following: + +```ts +import { NodeSDK } from '@opentelemetry/sdk-node'; +import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; +import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto'; +import { createAddHookMessageChannel } from 'import-in-the-middle'; +import { register } from 'module'; + +const { registerOptions } = createAddHookMessageChannel(); +register('import-in-the-middle/hook.mjs', import.meta.url, registerOptions); + +const sdk = new NodeSDK({ + serviceName: 'test-sveltekit-tracing', + traceExporter: new OTLPTraceExporter(), + instrumentations: [getNodeAutoInstrumentations()] +}); + +sdk.start(); +``` + +Any serverside requests will now begin generating traces, which you can view in Jaeger's web console at http://localhost:16686. From fb508f73d06026bee615a7f3566656cee30b6785 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Mon, 11 Aug 2025 17:13:29 -0600 Subject: [PATCH 32/74] types --- packages/kit/src/exports/public.d.ts | 6 +++--- packages/kit/types/index.d.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 49e7cffb8754..0b7c8a4c7c62 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -420,7 +420,7 @@ export interface KitConfig { /** * Whether to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), and [form actions](https://svelte.dev/docs/kit/form-actions). * @default { server: false } - * @since 2.26.0 // TODO: update this before publishing + * @since 2.28.0 */ tracing?: { server?: boolean; @@ -1304,7 +1304,7 @@ export interface RequestEvent< /** * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.26.0 // TODO: update this before publishing + * @since 2.28.0 */ tracing: { /** Whether tracing is enabled. */ @@ -1481,7 +1481,7 @@ export interface ServerLoadEvent< /** * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.26.0 // TODO: update this before publishing + * @since 2.28.0 */ tracing: { /** Whether tracing is enabled. */ diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 13c9b130bab6..6c3b97bf6dd0 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -397,7 +397,7 @@ declare module '@sveltejs/kit' { /** * Whether to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), and [form actions](https://svelte.dev/docs/kit/form-actions). * @default { server: false } - * @since 2.26.0 // TODO: update this before publishing + * @since 2.28.0 */ tracing?: { server?: boolean; @@ -1281,7 +1281,7 @@ declare module '@sveltejs/kit' { /** * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.26.0 // TODO: update this before publishing + * @since 2.28.0 */ tracing: { /** Whether tracing is enabled. */ @@ -1458,7 +1458,7 @@ declare module '@sveltejs/kit' { /** * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.26.0 // TODO: update this before publishing + * @since 2.28.0 */ tracing: { /** Whether tracing is enabled. */ From 4ccef4b4e32294672bf689b8c821cc6886a7cbf2 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Mon, 11 Aug 2025 17:14:26 -0600 Subject: [PATCH 33/74] types --- packages/kit/src/exports/public.d.ts | 2 +- packages/kit/types/index.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 0b7c8a4c7c62..0db0c8b4f67b 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -1016,7 +1016,7 @@ export interface LoadEvent< /** * Access to spans for tracing. If tracing is not enabled or the function is being run in the browser, these spans will do nothing. - * @since 2.26.0 // TODO: update this before publishing + * @since 2.28.0 */ tracing: { /** Whether tracing is enabled. */ diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 6c3b97bf6dd0..38524b63542d 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -993,7 +993,7 @@ declare module '@sveltejs/kit' { /** * Access to spans for tracing. If tracing is not enabled or the function is being run in the browser, these spans will do nothing. - * @since 2.26.0 // TODO: update this before publishing + * @since 2.28.0 */ tracing: { /** Whether tracing is enabled. */ From 21f84be11ffd53144005e2024273ce4d69a27c50 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Mon, 11 Aug 2025 19:06:38 -0600 Subject: [PATCH 34/74] fix: use resolve module --- packages/kit/src/exports/vite/dev/index.js | 23 +++++----------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 48e6b37fc5c7..0cbbe50dfe92 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -1,4 +1,4 @@ -import fs, { existsSync } from 'node:fs'; +import fs from 'node:fs'; import path from 'node:path'; import process from 'node:process'; import { URL } from 'node:url'; @@ -502,7 +502,10 @@ export async function dev(vite, vite_config, svelte_config) { return; } - await load_module_if_exists(vite, tracing.server); + const resolved_tracing = resolve_entry(tracing.server); + if (resolved_tracing) { + await vite.ssrLoadModule(resolved_tracing); + } // we have to import `Server` before calling `set_assets` const { Server } = /** @type {import('types').ServerModule} */ ( @@ -663,19 +666,3 @@ function has_correct_case(file, assets) { return false; } - -/** - * @param {import('vite').ViteDevServer} vite - * @param {string} path - * @returns {Promise} - */ -async function load_module_if_exists(vite, path) { - let extless_path = path; - if (extless_path.endsWith('.js') || extless_path.endsWith('.ts')) { - extless_path = extless_path.slice(-3); - } - - if (existsSync(`${extless_path}.js`) || existsSync(`${extless_path}.ts`)) { - await vite.ssrLoadModule(extless_path); - } -} From eb3e876e1c5a964bf887d7ecfab557d0028fdde9 Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Mon, 11 Aug 2025 19:08:05 -0600 Subject: [PATCH 35/74] feat: `tracing.server.ts` (#14117) * feat: Enable server-side instrumentation via tracing.server.ts This commit consolidates all changes to support server-side instrumentation: - Add support for tracing.server.ts configuration file - Implement adapter support for Netlify, Cloudflare, Vercel, and Node - Add better export generation and catalog functionality - Include necessary type definitions and configuration options - Fix various bugs and conflicts during development * make server tracing file separate from tracing config * make netlify do the thing * remove file * fix: Rollup issue * fix: Rollup config --- packages/adapter-cloudflare/index.js | 10 +- packages/adapter-netlify/index.js | 50 ++++++++- packages/adapter-node/index.js | 26 ++++- packages/adapter-vercel/index.js | 45 ++++++-- packages/kit/src/core/adapt/builder.js | 137 ++++++++++++++++++++++--- packages/kit/src/exports/public.d.ts | 39 +++++++ packages/kit/src/exports/vite/index.js | 10 ++ packages/kit/types/index.d.ts | 39 +++++++ 8 files changed, 325 insertions(+), 31 deletions(-) diff --git a/packages/adapter-cloudflare/index.js b/packages/adapter-cloudflare/index.js index fdbdf9a769ed..647bb9cdda13 100644 --- a/packages/adapter-cloudflare/index.js +++ b/packages/adapter-cloudflare/index.js @@ -113,6 +113,13 @@ export default function (options = {}) { ASSETS: assets_binding } }); + if (builder.hasServerTracingFile()) { + builder.trace({ + entrypoint: worker_dest, + tracing: `${builder.getServerDirectory()}/tracing.server.js`, + tla: false + }); + } // _headers if (existsSync('_headers')) { @@ -184,7 +191,8 @@ export default function (options = {}) { } return true; - } + }, + tracing: () => true } }; } diff --git a/packages/adapter-netlify/index.js b/packages/adapter-netlify/index.js index 876d57f3372c..59d6db2bc84d 100644 --- a/packages/adapter-netlify/index.js +++ b/packages/adapter-netlify/index.js @@ -1,3 +1,4 @@ +/** @import { BuildOptions } from 'esbuild' */ import { appendFileSync, existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs'; import { dirname, join, resolve, posix } from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -106,7 +107,8 @@ export default function ({ split = false, edge = edge_set_in_env_var } = {}) { } return true; - } + }, + tracing: () => true } }; } @@ -174,9 +176,8 @@ async function generate_edge_functions({ builder }) { version: 1 }; - await esbuild.build({ - entryPoints: [`${tmp}/entry.js`], - outfile: '.netlify/edge-functions/render.js', + /** @type {BuildOptions} */ + const esbuild_config = { bundle: true, format: 'esm', platform: 'browser', @@ -194,7 +195,29 @@ async function generate_edge_functions({ builder }) { // https://docs.netlify.com/edge-functions/api/#runtime-environment external: builtinModules.map((id) => `node:${id}`), alias: Object.fromEntries(builtinModules.map((id) => [id, `node:${id}`])) - }); + }; + await Promise.all([ + esbuild.build({ + entryPoints: [`${tmp}/entry.js`], + outfile: '.netlify/edge-functions/render.js', + ...esbuild_config + }), + builder.hasServerTracingFile() && + esbuild.build({ + entryPoints: [`${builder.getServerDirectory()}/tracing.server.js`], + outfile: '.netlify/edge/tracing.server.js', + ...esbuild_config + }) + ]); + + if (builder.hasServerTracingFile()) { + builder.trace({ + entrypoint: '.netlify/edge-functions/render.js', + tracing: '.netlify/edge/tracing.server.js', + tla: false, + start: '.netlify/edge/start.js' + }); + } writeFileSync('.netlify/edge-functions/manifest.json', JSON.stringify(edge_manifest)); } @@ -272,6 +295,14 @@ function generate_lambda_functions({ builder, publish, split }) { writeFileSync(`.netlify/functions-internal/${name}.mjs`, fn); writeFileSync(`.netlify/functions-internal/${name}.json`, fn_config); + if (builder.hasServerTracingFile()) { + builder.trace({ + entrypoint: `.netlify/functions-internal/${name}.mjs`, + tracing: '.netlify/server/tracing.server.js', + start: `.netlify/functions-start/${name}.start.mjs`, + exports: ['handler'] + }); + } const redirect = `/.netlify/functions/${name} 200`; redirects.push(`${pattern} ${redirect}`); @@ -286,6 +317,15 @@ function generate_lambda_functions({ builder, publish, split }) { writeFileSync(`.netlify/functions-internal/${FUNCTION_PREFIX}render.json`, fn_config); writeFileSync(`.netlify/functions-internal/${FUNCTION_PREFIX}render.mjs`, fn); + if (builder.hasServerTracingFile()) { + builder.trace({ + entrypoint: `.netlify/functions-internal/${FUNCTION_PREFIX}render.mjs`, + tracing: '.netlify/server/tracing.server.js', + start: `.netlify/functions-start/${FUNCTION_PREFIX}render.start.mjs`, + exports: ['handler'] + }); + } + redirects.push(`* /.netlify/functions/${FUNCTION_PREFIX}render 200`); } diff --git a/packages/adapter-node/index.js b/packages/adapter-node/index.js index 9b0b3158ab82..7ac3fcea1b06 100644 --- a/packages/adapter-node/index.js +++ b/packages/adapter-node/index.js @@ -48,14 +48,21 @@ export default function (opts = {}) { const pkg = JSON.parse(readFileSync('package.json', 'utf8')); + /** @type {Record} */ + const input = { + index: `${tmp}/index.js`, + manifest: `${tmp}/manifest.js` + }; + + if (builder.hasServerTracingFile()) { + input['tracing.server'] = `${tmp}/tracing.server.js`; + } + // we bundle the Vite output so that deployments only need // their production dependencies. Anything in devDependencies // will get included in the bundled code const bundle = await rollup({ - input: { - index: `${tmp}/index.js`, - manifest: `${tmp}/manifest.js` - }, + input, external: [ // dependencies could have deep exports, so we need a regex ...Object.keys(pkg.dependencies || {}).map((d) => new RegExp(`^${d}(\\/.*)?$`)) @@ -89,10 +96,19 @@ export default function (opts = {}) { ENV_PREFIX: JSON.stringify(envPrefix) } }); + + if (builder.hasServerTracingFile()) { + builder.trace({ + entrypoint: `${out}/index.js`, + tracing: `${out}/server/tracing.server.js`, + exports: ['path', 'host', 'port', 'server'] + }); + } }, supports: { - read: () => true + read: () => true, + tracing: () => true } }; } diff --git a/packages/adapter-vercel/index.js b/packages/adapter-vercel/index.js index 1586ef327d10..055b7e205d5a 100644 --- a/packages/adapter-vercel/index.js +++ b/packages/adapter-vercel/index.js @@ -1,3 +1,4 @@ +/** @import { BuildOptions } from 'esbuild' */ import fs from 'node:fs'; import path from 'node:path'; import process from 'node:process'; @@ -93,13 +94,18 @@ const plugin = function (defaults = {}) { const dir = `${dirs.functions}/${name}.func`; const relativePath = path.posix.relative(tmp, builder.getServerDirectory()); - builder.copy(`${files}/serverless.js`, `${tmp}/index.js`, { replace: { SERVER: `${relativePath}/index.js`, MANIFEST: './manifest.js' } }); + if (builder.hasServerTracingFile()) { + builder.trace({ + entrypoint: `${tmp}/index.js`, + tracing: `${builder.getServerDirectory()}/tracing.server.js` + }); + } write( `${tmp}/manifest.js`, @@ -136,9 +142,9 @@ const plugin = function (defaults = {}) { ); try { - const result = await esbuild.build({ - entryPoints: [`${tmp}/edge.js`], - outfile: `${dirs.functions}/${name}.func/index.js`, + const outdir = `${dirs.functions}/${name}.func`; + /** @type {BuildOptions} */ + const esbuild_config = { // minimum Node.js version supported is v14.6.0 that is mapped to ES2019 // https://edge-runtime.vercel.app/features/polyfills // TODO verify the latest ES version the edge runtime supports @@ -168,10 +174,34 @@ const plugin = function (defaults = {}) { '.eot': 'copy', '.otf': 'copy' } + }; + const result = await esbuild.build({ + entryPoints: [`${tmp}/edge.js`], + outfile: `${outdir}/index.js`, + ...esbuild_config }); - if (result.warnings.length > 0) { - const formatted = await esbuild.formatMessages(result.warnings, { + let instrumentation_result; + if (builder.hasServerTracingFile()) { + instrumentation_result = await esbuild.build({ + entryPoints: [`${builder.getServerDirectory()}/tracing.server.js`], + outfile: `${outdir}/tracing.server.js`, + ...esbuild_config + }); + + builder.trace({ + entrypoint: `${outdir}/index.js`, + tracing: `${outdir}/tracing.server.js`, + tla: false + }); + } + + const warnings = instrumentation_result + ? [...result.warnings, ...instrumentation_result.warnings] + : result.warnings; + + if (warnings.length > 0) { + const formatted = await esbuild.formatMessages(warnings, { kind: 'warning', color: true }); @@ -477,7 +507,8 @@ const plugin = function (defaults = {}) { } return true; - } + }, + tracing: () => true } }; }; diff --git a/packages/kit/src/core/adapt/builder.js b/packages/kit/src/core/adapt/builder.js index 69f67ff3a879..57f5025822a4 100644 --- a/packages/kit/src/core/adapt/builder.js +++ b/packages/kit/src/core/adapt/builder.js @@ -1,6 +1,10 @@ +/** @import { Builder } from '@sveltejs/kit' */ +/** @import { ResolvedConfig } from 'vite' */ +/** @import { RouteDefinition } from '@sveltejs/kit' */ +/** @import { RouteData, ValidatedConfig, BuildData, ServerMetadata, ServerMetadataRoute, Prerendered, PrerenderMap, Logger } from 'types' */ import colors from 'kleur'; import { createReadStream, createWriteStream, existsSync, statSync } from 'node:fs'; -import { extname, resolve } from 'node:path'; +import { extname, resolve, join, dirname, relative } from 'node:path'; import { pipeline } from 'node:stream'; import { promisify } from 'node:util'; import zlib from 'node:zlib'; @@ -12,6 +16,7 @@ import generate_fallback from '../postbuild/fallback.js'; import { write } from '../sync/utils.js'; import { list_files } from '../utils.js'; import { find_server_assets } from '../generate_manifest/find_server_assets.js'; +import { reserved } from '../env.js'; const pipe = promisify(pipeline); const extensions = ['.html', '.js', '.mjs', '.json', '.css', '.svg', '.xml', '.wasm']; @@ -19,16 +24,16 @@ const extensions = ['.html', '.js', '.mjs', '.json', '.css', '.svg', '.xml', '.w /** * Creates the Builder which is passed to adapters for building the application. * @param {{ - * config: import('types').ValidatedConfig; - * build_data: import('types').BuildData; - * server_metadata: import('types').ServerMetadata; - * route_data: import('types').RouteData[]; - * prerendered: import('types').Prerendered; - * prerender_map: import('types').PrerenderMap; - * log: import('types').Logger; - * vite_config: import('vite').ResolvedConfig; + * config: ValidatedConfig; + * build_data: BuildData; + * server_metadata: ServerMetadata; + * route_data: RouteData[]; + * prerendered: Prerendered; + * prerender_map: PrerenderMap; + * log: Logger; + * vite_config: ResolvedConfig; * }} opts - * @returns {import('@sveltejs/kit').Builder} + * @returns {Builder} */ export function create_builder({ config, @@ -40,7 +45,7 @@ export function create_builder({ log, vite_config }) { - /** @type {Map} */ + /** @type {Map} */ const lookup = new Map(); /** @@ -48,11 +53,11 @@ export function create_builder({ * we expose a stable type that adapters can use to group/filter routes */ const routes = route_data.map((route) => { - const { config, methods, page, api } = /** @type {import('types').ServerMetadataRoute} */ ( + const { config, methods, page, api } = /** @type {ServerMetadataRoute} */ ( server_metadata.routes.get(route.id) ); - /** @type {import('@sveltejs/kit').RouteDefinition} */ + /** @type {RouteDefinition} */ const facade = { id: route.id, api, @@ -229,6 +234,37 @@ export function create_builder({ writeServer(dest) { return copy(`${config.kit.outDir}/output/server`, dest); + }, + + hasServerTracingFile() { + return existsSync(`${config.kit.outDir}/output/server/tracing.server.js`); + }, + + trace({ + entrypoint, + tracing, + start = join(dirname(entrypoint), 'start.js'), + tla = true, + exports = ['default'] + }) { + if (!existsSync(tracing)) { + throw new Error( + `Tracing file ${tracing} not found. This is probably a bug in your adapter.` + ); + } + if (!existsSync(entrypoint)) { + throw new Error( + `Entrypoint file ${entrypoint} not found. This is probably a bug in your adapter.` + ); + } + + copy(entrypoint, start); + if (existsSync(`${entrypoint}.map`)) { + copy(`${entrypoint}.map`, `${start}.map`); + } + + rimraf(entrypoint); + write(entrypoint, create_tracing_facade({ entrypoint, tracing, start, exports, tla })); } }; } @@ -254,3 +290,78 @@ async function compress_file(file, format = 'gz') { await pipe(source, compress, destination); } + +/** + * Given a list of exports, generate a facade that: + * - Imports the tracing file + * - Imports `exports` from the entrypoint (dynamically, if `tla` is true) + * - Re-exports `exports` from the entrypoint + * + * `default` receives special treatment: It will be imported as `default` and exported with `export default`. + * + * @param {Required[0]>} opts + * @returns {string} + */ +function create_tracing_facade({ entrypoint, tracing, start, exports, tla }) { + const relative_tracing = relative(dirname(entrypoint), tracing); + const relative_start = relative(dirname(entrypoint), start); + const import_tracing = `import './${relative_tracing}';`; + + let alias_index = 0; + const aliases = new Map(); + + for (const name of exports.filter((name) => reserved.has(name))) { + /* + you can do evil things like `export { c as class }`. + in order to import these, you need to alias them, and then un-alias them when re-exporting + this map will allow us to generate the following: + import { class as _1 } from 'entrypoint'; + export { _1 as class }; + */ + let alias = `_${alias_index++}`; + while (exports.includes(alias)) { + alias = `_${alias_index++}`; + } + + aliases.set(name, alias); + } + + const import_statements = []; + const export_statements = []; + + for (const name of exports) { + const alias = aliases.get(name); + if (alias) { + if (tla) { + // TLA generates a `const {} = await import('entrypoint')` so we need to use object destructuring + import_statements.push(`${name}: ${alias}`); + } else { + // non-TLA generates a `import { name as alias } from 'entrypoint'` + import_statements.push(`${name} as ${alias}`); + } + + if (name !== 'default') { + export_statements.push(`${alias} as ${name}`); + } + } else { + import_statements.push(`${name}`); + + if (name !== 'default') { + export_statements.push(`${name}`); + } + } + } + + const default_alias = aliases.get('default'); + const entrypoint_facade = [ + tla + ? `const { ${import_statements.join(', ')} } = await import('./${relative_start}');` + : `import { ${import_statements.join(', ')} } from './${relative_start}';`, + default_alias ? `export default ${default_alias};` : '', + export_statements.length > 0 ? `export { ${export_statements.join(', ')} };` : '' + ] + .filter(Boolean) + .join('\n'); + + return `${import_tracing}\n${entrypoint_facade}`; +} diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 0db0c8b4f67b..38b6fb36599f 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -194,6 +194,45 @@ export interface Builder { } ) => string[]; + /** + * Check if the server tracing file exists. + * @returns true if the server tracing file exists, false otherwise + */ + hasServerTracingFile: () => boolean; + + /** + * Trace `entrypoint` with `tracing`. + * + * Renames `entrypoint` to `start` and creates a new module at + * `entrypoint` which imports `tracing` and then dynamically imports `start`. This allows + * the module hooks necessary for tracing libraries to be loaded prior to any application code. + * + * Caveats: + * - "Live exports" will not work. If your adapter uses live exports, your users will need to manually import the server instrumentation on startup. + * - If `tla` is `false`, OTEL auto-instrumentation may not work properly. Use it if your environment supports it. + * - Use {@link hasServerTracingFile} to check if the user has a server tracing file; if they don't, you shouldn't do this. + * + * @param options an object containing the following properties: + * @param options.entrypoint the path to the entrypoint to trace. + * @param options.tracing the path to the tracing file. + * @param options.start the name of the start file. This is what `entrypoint` will be renamed to. + * @param options.tla Whether to use top-level await. If `true`, the `tracing` file will be statically imported and then the `start` file will be dynamically imported. If `false`, both files will be serially imported. Auto-instrumentation will not work properly without a dynamic `await`. + * @param options.exports an array of exports to re-export from the entrypoint. `default` represents the default export. Defaults to `['default']`. + */ + trace: ({ + entrypoint, + tracing, + start, + tla, + exports + }: { + entrypoint: string; + tracing: string; + start?: string; + tla?: boolean; + exports?: string[]; + }) => void; + /** * Compress files in `directory` with gzip and brotli, where appropriate. Generates `.gz` and `.br` files alongside the originals. * @param {string} directory The directory containing the files to be compressed diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index a2dea78501b0..cd31d6645d74 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -739,6 +739,16 @@ Tips: input[name] = path.resolve(file); }); + // ...and the server tracing file + const server_tracing = resolve_entry(kit.files.tracing.server); + if (server_tracing) { + const { adapter } = kit; + if (adapter && !adapter.supports?.tracing?.()) { + throw new Error(`${server_tracing} is unsupported in ${adapter.name}.`); + } + input['tracing.server'] = server_tracing; + } + // ...and every .remote file for (const remote of manifest_data.remotes) { input[`remote/${remote.hash}`] = path.resolve(remote.file); diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 38524b63542d..0be2f2beff48 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -171,6 +171,45 @@ declare module '@sveltejs/kit' { } ) => string[]; + /** + * Check if the server tracing file exists. + * @returns true if the server tracing file exists, false otherwise + */ + hasServerTracingFile: () => boolean; + + /** + * Trace `entrypoint` with `tracing`. + * + * Renames `entrypoint` to `start` and creates a new module at + * `entrypoint` which imports `tracing` and then dynamically imports `start`. This allows + * the module hooks necessary for tracing libraries to be loaded prior to any application code. + * + * Caveats: + * - "Live exports" will not work. If your adapter uses live exports, your users will need to manually import the server instrumentation on startup. + * - If `tla` is `false`, OTEL auto-instrumentation may not work properly. Use it if your environment supports it. + * - Use {@link hasServerTracingFile} to check if the user has a server tracing file; if they don't, you shouldn't do this. + * + * @param options an object containing the following properties: + * @param options.entrypoint the path to the entrypoint to trace. + * @param options.tracing the path to the tracing file. + * @param options.start the name of the start file. This is what `entrypoint` will be renamed to. + * @param options.tla Whether to use top-level await. If `true`, the `tracing` file will be statically imported and then the `start` file will be dynamically imported. If `false`, both files will be serially imported. Auto-instrumentation will not work properly without a dynamic `await`. + * @param options.exports an array of exports to re-export from the entrypoint. `default` represents the default export. Defaults to `['default']`. + */ + trace: ({ + entrypoint, + tracing, + start, + tla, + exports + }: { + entrypoint: string; + tracing: string; + start?: string; + tla?: boolean; + exports?: string[]; + }) => void; + /** * Compress files in `directory` with gzip and brotli, where appropriate. Generates `.gz` and `.br` files alongside the originals. * @param directory The directory containing the files to be compressed From c73569c9fce53efc0221ecdf888eca29413c32f6 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Mon, 11 Aug 2025 19:20:17 -0600 Subject: [PATCH 36/74] server file option --- packages/kit/src/core/config/index.spec.js | 2 +- packages/kit/src/core/config/options.js | 3 ++- packages/kit/src/exports/public.d.ts | 14 +++++++++++++- packages/kit/src/exports/vite/index.js | 5 +++++ packages/kit/types/index.d.ts | 16 ++++++++++++++-- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/packages/kit/src/core/config/index.spec.js b/packages/kit/src/core/config/index.spec.js index 4c8a1be7f876..dfc045b0716d 100644 --- a/packages/kit/src/core/config/index.spec.js +++ b/packages/kit/src/core/config/index.spec.js @@ -77,7 +77,7 @@ const get_defaults = (prefix = '') => ({ privatePrefix: '' }, experimental: { - tracing: { server: false }, + tracing: { server: false, serverFile: false }, remoteFunctions: false }, files: { diff --git a/packages/kit/src/core/config/options.js b/packages/kit/src/core/config/options.js index 646240171b08..e26c57409560 100644 --- a/packages/kit/src/core/config/options.js +++ b/packages/kit/src/core/config/options.js @@ -122,7 +122,8 @@ const options = object( experimental: object({ tracing: object({ - server: boolean(false) + server: boolean(false), + serverFile: boolean(false) }), remoteFunctions: boolean(false) }), diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index fa14bcc67ad5..3af94ad113bb 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -458,11 +458,23 @@ export interface KitConfig { experimental?: { /** * Whether to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), and [form actions](https://svelte.dev/docs/kit/form-actions). - * @default { server: false } + * @default { server: false, serverFile: false } * @since 2.28.0 */ tracing?: { + /** + * Enables server-side [OpenTelemetry](https://opentelemetry.io/) span emission for SvelteKit operations includeing the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). + * @default false + * @since 2.28.0 + */ server?: boolean; + + /** + * Enables `tracing.server.js` for tracing instrumentation. + * @default false + * @since 2.28.0 + */ + serverFile?: boolean; }; /** diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index cd31d6645d74..8dfe4a4d0693 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -746,6 +746,11 @@ Tips: if (adapter && !adapter.supports?.tracing?.()) { throw new Error(`${server_tracing} is unsupported in ${adapter.name}.`); } + if (!kit.experimental.tracing.serverFile) { + throw new Error( + '`tracing.server.js` is experimental. To use it, set `kit.experimental.tracing.serverFile`.' + ); + } input['tracing.server'] = server_tracing; } diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 898979fe3432..47da851b14d1 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -435,11 +435,23 @@ declare module '@sveltejs/kit' { experimental?: { /** * Whether to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), and [form actions](https://svelte.dev/docs/kit/form-actions). - * @default { server: false } + * @default { server: false, serverFile: false } * @since 2.28.0 */ tracing?: { + /** + * Enables server-side [OpenTelemetry](https://opentelemetry.io/) span emission for SvelteKit operations includeing the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). + * @default false + * @since 2.28.0 + */ server?: boolean; + + /** + * Enables `tracing.server.js` for tracing instrumentation. + * @default false + * @since 2.28.0 + */ + serverFile?: boolean; }; /** @@ -1071,7 +1083,7 @@ declare module '@sveltejs/kit' { * Information about the target of a specific navigation. */ export interface NavigationTarget< - Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, + Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, RouteId extends AppRouteId | null = AppRouteId | null > { /** From f6547844b4b2cefee9a3e9d4b131a1fd42190a3d Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Mon, 11 Aug 2025 19:21:24 -0600 Subject: [PATCH 37/74] docs --- documentation/docs/30-advanced/68-observability.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/documentation/docs/30-advanced/68-observability.md b/documentation/docs/30-advanced/68-observability.md index b6ff18d68e10..38c7bff28629 100644 --- a/documentation/docs/30-advanced/68-observability.md +++ b/documentation/docs/30-advanced/68-observability.md @@ -16,20 +16,21 @@ Sometimes, you may need to observe how your application is behaving in order to - Form actions - Remote Functions -To enable these spans, add the following to your `svelte.config.js`'s `kit` configuration: +Just telling SvelteKit to emit spans won't get you far, though -- you need to actually collect them somewhere to be able to view them. SvelteKit provides `src/tracing.server.ts` as a place to write your tracing setup and instrumentation code. It's guaranteed to be run prior to your application code being imported. + +To enable both of these features, add the following to your `svelte.config.js`'s `kit` configuration: ```ts { experimental: { tracing: { - server: true + server: true, + serverFile: true, } } } ``` -Just telling SvelteKit to emit spans won't get you far, though -- you need to actually collect them somewhere to be able to view them. SvelteKit provides `src/tracing.server.ts` as a place to write your tracing setup and instrumentation code. It's guaranteed to be run prior to your application code being imported. - > [!NOTE] Tracing -- and more significantly, tracing instrumentation -- can have a nontrivial overhead. Before you go all-in on tracing, consider whether or not you really need it, or if it might be more appropriate to turn it on in development and preview environments only. ## Development Quickstart From 5f5129c60a66fe2968a8e7859bd2c2694a65ceba Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Tue, 12 Aug 2025 15:08:25 -0600 Subject: [PATCH 38/74] feedback --- .../99-writing-adapters.md | 4 + .../docs/30-advanced/68-observability.md | 47 +++++----- packages/adapter-auto/index.js | 3 + packages/adapter-vercel/index.js | 23 ++++- packages/kit/src/core/adapt/builder.js | 39 +++++---- packages/kit/src/exports/hooks/sequence.js | 5 +- .../kit/src/exports/hooks/sequence.spec.js | 21 +++-- .../kit/src/exports/internal/event-state.js | 2 +- packages/kit/src/exports/internal/index.js | 2 +- packages/kit/src/exports/public.d.ts | 45 +++++----- packages/kit/src/exports/vite/index.js | 14 ++- packages/kit/src/exports/vite/utils.js | 48 ++++++++++ packages/kit/src/exports/vite/utils.spec.js | 87 ++++++++++++++++++- .../src/runtime/app/server/remote/shared.js | 2 +- .../kit/src/runtime/server/page/actions.js | 8 +- packages/kit/types/index.d.ts | 44 +++++----- 16 files changed, 288 insertions(+), 106 deletions(-) diff --git a/documentation/docs/25-build-and-deploy/99-writing-adapters.md b/documentation/docs/25-build-and-deploy/99-writing-adapters.md index a2bfb50cd7b2..56723f7de3f5 100644 --- a/documentation/docs/25-build-and-deploy/99-writing-adapters.md +++ b/documentation/docs/25-build-and-deploy/99-writing-adapters.md @@ -34,6 +34,10 @@ export default function (options) { // Return `true` if the route with the given `config` can use `read` // from `$app/server` in production, return `false` if it can't. // Or throw a descriptive error describing how to configure the deployment + }, + tracing: () => { + // Return `true` if this adapter supports loading `tracing.server.js`. + // Return `false if it can't, or throw a descriptive error. } } }; diff --git a/documentation/docs/30-advanced/68-observability.md b/documentation/docs/30-advanced/68-observability.md index 38c7bff28629..b2e8d6a0eb76 100644 --- a/documentation/docs/30-advanced/68-observability.md +++ b/documentation/docs/30-advanced/68-observability.md @@ -3,42 +3,47 @@ title: Observability ---
-

Available since 2.28

+

Available since 2.29

> [!NOTE] This feature is experimental. Expect bugs and breaking changes in minor versions (though we'll do our best to keep those to an absolute minimum). Please provide feedback! -Sometimes, you may need to observe how your application is behaving in order to improve performance or find the root cause of a pesky bug. To help with this, SvelteKit can emit serverside [OpenTelemetry](https://opentelemetry.io) spans for the following: +Sometimes, you may need to observe how your application is behaving in order to improve performance or find the root cause of a pesky bug. To help with this, SvelteKit can emit server-side [OpenTelemetry](https://opentelemetry.io) spans for the following: -- `handle` -- `sequence` (`sequence`d `handle` functions will show up as children of each other and the root handle hook) -- `load` (includes univeral `load`s when they're run on the server) +- `handle` hook (`sequence`d `handle` functions will show up as children of each other and the root handle hook) +- `load` functions (includes univeral `load` functions when they're run on the server) - Form actions -- Remote Functions +- Remote functions Just telling SvelteKit to emit spans won't get you far, though -- you need to actually collect them somewhere to be able to view them. SvelteKit provides `src/tracing.server.ts` as a place to write your tracing setup and instrumentation code. It's guaranteed to be run prior to your application code being imported. -To enable both of these features, add the following to your `svelte.config.js`'s `kit` configuration: - -```ts -{ - experimental: { - tracing: { - server: true, - serverFile: true, - } - } -} +To enable both of these features, add the following to your `svelte.config.js`: + +```diff +/// file: svelte.config.js +export default { + kit: { + +++experimental: { + tracing: { + server: true, + serverFile: true + } + }+++ + } +}; ``` > [!NOTE] Tracing -- and more significantly, tracing instrumentation -- can have a nontrivial overhead. Before you go all-in on tracing, consider whether or not you really need it, or if it might be more appropriate to turn it on in development and preview environments only. ## Development Quickstart -To view your first trace, you'll need to set up a local collector. We recommend [Jaeger](https://www.jaegertracing.io/docs/2.7/getting-started/), as they provide an easy-to-use quickstart command. Once your collector is running locally: +To view your first trace, you'll need to set up a local collector. We'll use [Jaeger](https://www.jaegertracing.io/docs/getting-started/) in this example, as they provide an easy-to-use quickstart command. Once your collector is running locally: -- Turn on the experemental flag from above in your `svelte.config.js` -- Use your package manager to install `@opentelemetry/sdk-node`, `opentelemetry/auto-instrumentations-node`, `@opentelemetry/exporter-trace-otlp-proto`, and `import-in-the-middle` +- Turn on the experimental flag mentioned above in your `svelte.config.js` file +- Use your package manager to install `@opentelemetry/sdk-node`, `@opentelemetry/auto-instrumentations-node`, `@opentelemetry/exporter-trace-otlp-proto`, and `import-in-the-middle` + ```sh + npm i @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-oltp-proto import-in-the-middle + ``` - Create `src/tracing.server.ts` with the following: ```ts @@ -60,4 +65,4 @@ const sdk = new NodeSDK({ sdk.start(); ``` -Any serverside requests will now begin generating traces, which you can view in Jaeger's web console at http://localhost:16686. +Any server-side requests will now begin generating traces, which you can view in Jaeger's web console at [localhost:16686](http://localhost:16686). diff --git a/packages/adapter-auto/index.js b/packages/adapter-auto/index.js index ba8244e59d90..578c8115c02d 100644 --- a/packages/adapter-auto/index.js +++ b/packages/adapter-auto/index.js @@ -152,6 +152,9 @@ export default () => ({ supports_error( 'The read function imported from $app/server only works in certain environments' ); + }, + tracing: () => { + supports_error('`tracing.server.js` only works in certain environments'); } } }); diff --git a/packages/adapter-vercel/index.js b/packages/adapter-vercel/index.js index 055b7e205d5a..3062952a9ab4 100644 --- a/packages/adapter-vercel/index.js +++ b/packages/adapter-vercel/index.js @@ -192,7 +192,9 @@ const plugin = function (defaults = {}) { builder.trace({ entrypoint: `${outdir}/index.js`, tracing: `${outdir}/tracing.server.js`, - tla: false + module: { + generateText: generate_traced_edge_module + } }); } @@ -835,4 +837,23 @@ function is_prerendered(route) { ); } +/** + * @param {{ tracing: string; start: string }} opts + */ +function generate_traced_edge_module({ tracing, start }) { + return `\ +import './${tracing}'; +const promise = import('./${start}'); + +/** + * @param {import('http').IncomingMessage} req + * @param {import('http').ServerResponse} res + */ +export default async (req, res) => { + const { default: handler } = await promise; + return handler(req, res); +} +`; +} + export default plugin; diff --git a/packages/kit/src/core/adapt/builder.js b/packages/kit/src/core/adapt/builder.js index 57f5025822a4..e4993fecdc0c 100644 --- a/packages/kit/src/core/adapt/builder.js +++ b/packages/kit/src/core/adapt/builder.js @@ -244,8 +244,9 @@ export function create_builder({ entrypoint, tracing, start = join(dirname(entrypoint), 'start.js'), - tla = true, - exports = ['default'] + module = { + exports: ['default'] + } }) { if (!existsSync(tracing)) { throw new Error( @@ -263,8 +264,20 @@ export function create_builder({ copy(`${entrypoint}.map`, `${start}.map`); } + const relative_tracing = relative(dirname(entrypoint), tracing); + const relative_start = relative(dirname(entrypoint), start); + + const facade = + 'generateText' in module + ? module.generateText({ tracing: relative_tracing, start: relative_start }) + : create_tracing_facade({ + tracing: relative_tracing, + start: relative_start, + exports: module.exports + }); + rimraf(entrypoint); - write(entrypoint, create_tracing_facade({ entrypoint, tracing, start, exports, tla })); + write(entrypoint, facade); } }; } @@ -299,13 +312,11 @@ async function compress_file(file, format = 'gz') { * * `default` receives special treatment: It will be imported as `default` and exported with `export default`. * - * @param {Required[0]>} opts + * @param {{ tracing: string; start: string; exports: string[] }} opts * @returns {string} */ -function create_tracing_facade({ entrypoint, tracing, start, exports, tla }) { - const relative_tracing = relative(dirname(entrypoint), tracing); - const relative_start = relative(dirname(entrypoint), start); - const import_tracing = `import './${relative_tracing}';`; +function create_tracing_facade({ tracing, start, exports }) { + const import_tracing = `import './${tracing}';`; let alias_index = 0; const aliases = new Map(); @@ -332,13 +343,7 @@ function create_tracing_facade({ entrypoint, tracing, start, exports, tla }) { for (const name of exports) { const alias = aliases.get(name); if (alias) { - if (tla) { - // TLA generates a `const {} = await import('entrypoint')` so we need to use object destructuring - import_statements.push(`${name}: ${alias}`); - } else { - // non-TLA generates a `import { name as alias } from 'entrypoint'` - import_statements.push(`${name} as ${alias}`); - } + import_statements.push(`${name}: ${alias}`); if (name !== 'default') { export_statements.push(`${alias} as ${name}`); @@ -354,9 +359,7 @@ function create_tracing_facade({ entrypoint, tracing, start, exports, tla }) { const default_alias = aliases.get('default'); const entrypoint_facade = [ - tla - ? `const { ${import_statements.join(', ')} } = await import('./${relative_start}');` - : `import { ${import_statements.join(', ')} } from './${relative_start}';`, + `const { ${import_statements.join(', ')} } = await import('./${start}');`, default_alias ? `export default ${default_alias};` : '', export_statements.length > 0 ? `export { ${export_statements.join(', ')} };` : '' ] diff --git a/packages/kit/src/exports/hooks/sequence.js b/packages/kit/src/exports/hooks/sequence.js index 99ad93e42586..34c3b9915c47 100644 --- a/packages/kit/src/exports/hooks/sequence.js +++ b/packages/kit/src/exports/hooks/sequence.js @@ -89,10 +89,11 @@ export function sequence(...handlers) { function apply_handle(i, event, parent_options) { const handle = handlers[i]; + console.log('in sequence', get_event_state(event)); return get_event_state(event).tracing.record_span({ - name: 'sveltekit.handle.child', + name: 'sveltekit.handle.sequenced.${i}', attributes: { - 'sveltekit.handle.child.index': i + 'sveltekit.handle.sequenced.name': handle.name }, fn: async (current) => { const traced_event = merge_tracing(event, current); diff --git a/packages/kit/src/exports/hooks/sequence.spec.js b/packages/kit/src/exports/hooks/sequence.spec.js index 800d6dc1b8e8..5e2fe5d4c66d 100644 --- a/packages/kit/src/exports/hooks/sequence.spec.js +++ b/packages/kit/src/exports/hooks/sequence.spec.js @@ -1,21 +1,20 @@ import { assert, expect, test } from 'vitest'; import { sequence } from './sequence.js'; import { installPolyfills } from '../node/polyfills.js'; -import { EVENT_STATE } from '@sveltejs/kit/internal'; +import { add_event_state } from '@sveltejs/kit/internal'; installPolyfills(); -const dummy_event = /** @type {import('@sveltejs/kit').RequestEvent} */ ( - /** @type {unknown} */ ({ - tracing: { root: {} }, - [EVENT_STATE]: { - tracing: { - // @ts-expect-error - record_span: ({ fn }) => fn() - } +const dummy_event = add_event_state({ + // @ts-expect-error + record_span: ({ fn }) => fn(), + event: { + tracing: { + // @ts-expect-error + root: {} } - }) -); + } +}); test('applies handlers in sequence', async () => { /** @type {string[]} */ diff --git a/packages/kit/src/exports/internal/event-state.js b/packages/kit/src/exports/internal/event-state.js index fd1166ea0dba..f519cddac3a3 100644 --- a/packages/kit/src/exports/internal/event-state.js +++ b/packages/kit/src/exports/internal/event-state.js @@ -1,7 +1,7 @@ /** @import { RequestEvent } from '@sveltejs/kit' */ /** @import { MaybePromise, PrerenderOptions, ServerHooks, SSROptions, SSRState, RecordSpan } from 'types' */ -export const EVENT_STATE = Symbol('remote'); +export const EVENT_STATE = Symbol('sveltekit private event state'); /** * Internal state associated with the current `RequestEvent`, diff --git a/packages/kit/src/exports/internal/index.js b/packages/kit/src/exports/internal/index.js index ada44b6cb821..3a66d6b6289c 100644 --- a/packages/kit/src/exports/internal/index.js +++ b/packages/kit/src/exports/internal/index.js @@ -64,7 +64,7 @@ export class ActionFailure { export { with_event, getRequestEvent } from './event.js'; -export { EVENT_STATE, get_event_state, create_event_state } from './event-state.js'; +export { get_event_state, create_event_state, EVENT_STATE } from './event-state.js'; export { validate_remote_functions } from './remote-functions.js'; diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 3af94ad113bb..fbe6eab3154e 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -55,6 +55,7 @@ export interface Adapter { /** * Test support for `tracing`. To pass, the adapter must support `tracing.server.js` and * also deploy to a platform that supports `@opentelemetry/api`. + * @since 2.29.0 */ tracing?: () => boolean; }; @@ -197,6 +198,7 @@ export interface Builder { /** * Check if the server tracing file exists. * @returns true if the server tracing file exists, false otherwise + * @since 2.29.0 */ hasServerTracingFile: () => boolean; @@ -216,21 +218,22 @@ export interface Builder { * @param options.entrypoint the path to the entrypoint to trace. * @param options.tracing the path to the tracing file. * @param options.start the name of the start file. This is what `entrypoint` will be renamed to. - * @param options.tla Whether to use top-level await. If `true`, the `tracing` file will be statically imported and then the `start` file will be dynamically imported. If `false`, both files will be serially imported. Auto-instrumentation will not work properly without a dynamic `await`. - * @param options.exports an array of exports to re-export from the entrypoint. `default` represents the default export. Defaults to `['default']`. - */ - trace: ({ - entrypoint, - tracing, - start, - tla, - exports - }: { + * @param options.module configuration for the resulting entrypoint module. + * @param options.module.exports + * @param options.module.generateText a function that receives the relative paths to the tracing and start files, and generates the text of the module to be traced. If not provided, the default implementation will be used, which uses top-level await. + * @since 2.29.0 + */ + trace: (args: { entrypoint: string; tracing: string; start?: string; - tla?: boolean; - exports?: string[]; + module?: + | { + exports: string[]; + } + | { + generateText: (args: { tracing: string; start: string }) => string; + }; }) => void; /** @@ -454,25 +457,25 @@ export interface KitConfig { */ privatePrefix?: string; }; - /** Experimental features. Here be dragons. Breaking changes may occur in minor releases. */ + /** Experimental features. Here be dragons. These are not subject to semantic versioning, so breaking changes or removal can happen in any release. */ experimental?: { /** - * Whether to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), and [form actions](https://svelte.dev/docs/kit/form-actions). + * Options for enabling to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). * @default { server: false, serverFile: false } - * @since 2.28.0 + * @since 2.29.0 */ tracing?: { /** - * Enables server-side [OpenTelemetry](https://opentelemetry.io/) span emission for SvelteKit operations includeing the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). + * Enables server-side [OpenTelemetry](https://opentelemetry.io/) span emission for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). * @default false - * @since 2.28.0 + * @since 2.29.0 */ server?: boolean; /** * Enables `tracing.server.js` for tracing instrumentation. * @default false - * @since 2.28.0 + * @since 2.29.0 */ serverFile?: boolean; }; @@ -1067,7 +1070,7 @@ export interface LoadEvent< /** * Access to spans for tracing. If tracing is not enabled or the function is being run in the browser, these spans will do nothing. - * @since 2.28.0 + * @since 2.29.0 */ tracing: { /** Whether tracing is enabled. */ @@ -1358,7 +1361,7 @@ export interface RequestEvent< /** * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.28.0 + * @since 2.29.0 */ tracing: { /** Whether tracing is enabled. */ @@ -1535,7 +1538,7 @@ export interface ServerLoadEvent< /** * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.28.0 + * @since 2.29.0 */ tracing: { /** Whether tracing is enabled. */ diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index 8dfe4a4d0693..da58dbac6d29 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -17,7 +17,13 @@ import { assets_base, find_deps, resolve_symlinks } from './build/utils.js'; import { dev } from './dev/index.js'; import { is_illegal, module_guard } from './graph_analysis/index.js'; import { preview } from './preview/index.js'; -import { get_config_aliases, get_env, normalize_id, strip_virtual_prefix } from './utils.js'; +import { + error_for_missing_config, + get_config_aliases, + get_env, + normalize_id, + strip_virtual_prefix +} from './utils.js'; import { write_client_manifest } from '../../core/sync/write_client_manifest.js'; import prerender from '../../core/postbuild/prerender.js'; import analyse from '../../core/postbuild/analyse.js'; @@ -747,8 +753,10 @@ Tips: throw new Error(`${server_tracing} is unsupported in ${adapter.name}.`); } if (!kit.experimental.tracing.serverFile) { - throw new Error( - '`tracing.server.js` is experimental. To use it, set `kit.experimental.tracing.serverFile`.' + error_for_missing_config( + 'tracing.server.js', + 'kit.experimental.tracing.serverFile', + 'true' ); } input['tracing.server'] = server_tracing; diff --git a/packages/kit/src/exports/vite/utils.js b/packages/kit/src/exports/vite/utils.js index 02916e4d85c5..f059fcceb8fe 100644 --- a/packages/kit/src/exports/vite/utils.js +++ b/packages/kit/src/exports/vite/utils.js @@ -4,6 +4,7 @@ import { posixify } from '../../utils/filesystem.js'; import { negotiate } from '../../utils/http.js'; import { filter_private_env, filter_public_env } from '../../utils/env.js'; import { escape_html } from '../../utils/escape.js'; +import { dedent } from '../../core/sync/utils.js'; import { app_server, env_dynamic_private, @@ -156,3 +157,50 @@ export function normalize_id(id, lib, cwd) { } export const strip_virtual_prefix = /** @param {string} id */ (id) => id.replace('\0virtual:', ''); + +/** + * For `error_for_missing_config('tracing.server.js', 'kit.experimental.tracing.serverFile', true)`, + * returns: + * + * ``` + * To enable `tracing.server.js`, add the following to your `svelte.config.js`: + * + *\`\`\`js + * kit: + * experimental: + * tracing: + * server: true + * } + * } + * } + *\`\`\` + *``` + * @param {string} feature_name + * @param {string} path + * @param {string} value + * @returns {never} + */ +export function error_for_missing_config(feature_name, path, value) { + const parts = path.split('.'); + const hole = '__HOLE__'; + /** @param {number} n */ + const indent = (n) => ' '.repeat(n); + + const result = parts.reduce((acc, part, i) => { + if (i === parts.length - 1) { + return acc.replace(hole, `${indent(i)}${part}: ${value}`); + } else { + return acc.replace(hole, `${indent(i)}${part}: {\n${hole}\n${indent(i)}}`); + } + }, hole); + + throw new Error( + dedent`\ + To enable \`${feature_name}\`, add the following to your \`svelte.config.js\`: + + \`\`\`js + ${result} + \`\`\` + ` + ); +} diff --git a/packages/kit/src/exports/vite/utils.spec.js b/packages/kit/src/exports/vite/utils.spec.js index 45569b13f5c7..f329c3154ee8 100644 --- a/packages/kit/src/exports/vite/utils.spec.js +++ b/packages/kit/src/exports/vite/utils.spec.js @@ -2,7 +2,8 @@ import path from 'node:path'; import { expect, test } from 'vitest'; import { validate_config } from '../../core/config/index.js'; import { posixify } from '../../utils/filesystem.js'; -import { get_config_aliases } from './utils.js'; +import { dedent } from '../../core/sync/utils.js'; +import { get_config_aliases, error_for_missing_config } from './utils.js'; test('transform kit.alias to resolve.alias', () => { const config = validate_config({ @@ -37,3 +38,87 @@ test('transform kit.alias to resolve.alias', () => { { find: /^\$regexChar\/(.+)$/.toString(), replacement: 'windows/path/$1' } ]); }); + +test('error_for_missing_config - simple single level config', () => { + expect(() => error_for_missing_config('feature', 'kit.adapter', 'true')).toThrow( + dedent` + To enable \`feature\`, add the following to your \`svelte.config.js\`: + + \`\`\`js + kit: { + adapter: true + } + \`\`\` + ` + ); +}); + +test('error_for_missing_config - nested config', () => { + expect(() => + error_for_missing_config('tracing.server.js', 'kit.experimental.tracing.serverFile', 'true') + ).toThrow( + dedent` + To enable \`tracing.server.js\`, add the following to your \`svelte.config.js\`: + + \`\`\`js + kit: { + experimental: { + tracing: { + serverFile: true + } + } + } + \`\`\` + ` + ); +}); + +test('error_for_missing_config - deeply nested config', () => { + expect(() => error_for_missing_config('deep feature', 'a.b.c.d.e', '"value"')).toThrow( + dedent` + To enable \`deep feature\`, add the following to your \`svelte.config.js\`: + + \`\`\`js + a: { + b: { + c: { + d: { + e: "value" + } + } + } + } + \`\`\` + ` + ); +}); + +test('error_for_missing_config - two level config', () => { + expect(() => error_for_missing_config('some feature', 'kit.someFeature', 'false')).toThrow( + dedent` + To enable \`some feature\`, add the following to your \`svelte.config.js\`: + + \`\`\`js + kit: { + someFeature: false + } + \`\`\` + ` + ); +}); + +test('error_for_missing_config - handles special characters in feature name', () => { + expect(() => + error_for_missing_config('special-feature.js', 'kit.special', '{ enabled: true }') + ).toThrow( + dedent` + To enable \`special-feature.js\`, add the following to your \`svelte.config.js\`: + + \`\`\`js + kit: { + special: { enabled: true } + } + \`\`\` + ` + ); +}); diff --git a/packages/kit/src/runtime/app/server/remote/shared.js b/packages/kit/src/runtime/app/server/remote/shared.js index 3b188fd98df6..c0155c00d211 100644 --- a/packages/kit/src/runtime/app/server/remote/shared.js +++ b/packages/kit/src/runtime/app/server/remote/shared.js @@ -2,7 +2,7 @@ /** @import { ServerHooks, MaybePromise } from 'types' */ import { parse } from 'devalue'; import { error } from '@sveltejs/kit'; -import { getRequestEvent, with_event, EVENT_STATE, get_event_state } from '@sveltejs/kit/internal'; +import { getRequestEvent, with_event, get_event_state } from '@sveltejs/kit/internal'; import { create_remote_cache_key, stringify_remote_arg } from '../../../shared.js'; /** diff --git a/packages/kit/src/runtime/server/page/actions.js b/packages/kit/src/runtime/server/page/actions.js index 3d607ffed55f..83d089d326d8 100644 --- a/packages/kit/src/runtime/server/page/actions.js +++ b/packages/kit/src/runtime/server/page/actions.js @@ -257,17 +257,17 @@ async function call_action(event, actions) { } return record_span({ - name: 'sveltekit.action', + name: 'sveltekit.form_action', attributes: { - 'sveltekit.action.name': name, + 'sveltekit.form_action.name': name, 'http.route': event.route.id || 'unknown' }, fn: async (current) => { const result = await with_event(merge_tracing(event, current), () => action(event)); if (result instanceof ActionFailure) { current.setAttributes({ - 'sveltekit.action.result.type': 'failure', - 'sveltekit.action.result.status': result.status + 'sveltekit.form_action.result.type': 'failure', + 'sveltekit.form_action.result.status': result.status }); } diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 47da851b14d1..ca16ff8496db 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -32,6 +32,7 @@ declare module '@sveltejs/kit' { /** * Test support for `tracing`. To pass, the adapter must support `tracing.server.js` and * also deploy to a platform that supports `@opentelemetry/api`. + * @since 2.29.0 */ tracing?: () => boolean; }; @@ -174,6 +175,7 @@ declare module '@sveltejs/kit' { /** * Check if the server tracing file exists. * @returns true if the server tracing file exists, false otherwise + * @since 2.29.0 */ hasServerTracingFile: () => boolean; @@ -193,21 +195,21 @@ declare module '@sveltejs/kit' { * @param options.entrypoint the path to the entrypoint to trace. * @param options.tracing the path to the tracing file. * @param options.start the name of the start file. This is what `entrypoint` will be renamed to. - * @param options.tla Whether to use top-level await. If `true`, the `tracing` file will be statically imported and then the `start` file will be dynamically imported. If `false`, both files will be serially imported. Auto-instrumentation will not work properly without a dynamic `await`. - * @param options.exports an array of exports to re-export from the entrypoint. `default` represents the default export. Defaults to `['default']`. - */ - trace: ({ - entrypoint, - tracing, - start, - tla, - exports - }: { + * @param options.module configuration for the resulting entrypoint module. + * @param options.module.generateText a function that receives the relative paths to the tracing and start files, and generates the text of the module to be traced. If not provided, the default implementation will be used, which uses top-level await. + * @since 2.29.0 + */ + trace: (args: { entrypoint: string; tracing: string; start?: string; - tla?: boolean; - exports?: string[]; + module?: + | { + exports: string[]; + } + | { + generateText: (args: { tracing: string; start: string }) => string; + }; }) => void; /** @@ -431,25 +433,25 @@ declare module '@sveltejs/kit' { */ privatePrefix?: string; }; - /** Experimental features. Here be dragons. Breaking changes may occur in minor releases. */ + /** Experimental features. Here be dragons. These are not subject to semantic versioning, so breaking changes or removal can happen in any release. */ experimental?: { /** - * Whether to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), and [form actions](https://svelte.dev/docs/kit/form-actions). + * Options for enabling to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). * @default { server: false, serverFile: false } - * @since 2.28.0 + * @since 2.29.0 */ tracing?: { /** - * Enables server-side [OpenTelemetry](https://opentelemetry.io/) span emission for SvelteKit operations includeing the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). + * Enables server-side [OpenTelemetry](https://opentelemetry.io/) span emission for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). * @default false - * @since 2.28.0 + * @since 2.29.0 */ server?: boolean; /** * Enables `tracing.server.js` for tracing instrumentation. * @default false - * @since 2.28.0 + * @since 2.29.0 */ serverFile?: boolean; }; @@ -1044,7 +1046,7 @@ declare module '@sveltejs/kit' { /** * Access to spans for tracing. If tracing is not enabled or the function is being run in the browser, these spans will do nothing. - * @since 2.28.0 + * @since 2.29.0 */ tracing: { /** Whether tracing is enabled. */ @@ -1335,7 +1337,7 @@ declare module '@sveltejs/kit' { /** * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.28.0 + * @since 2.29.0 */ tracing: { /** Whether tracing is enabled. */ @@ -1512,7 +1514,7 @@ declare module '@sveltejs/kit' { /** * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.28.0 + * @since 2.29.0 */ tracing: { /** Whether tracing is enabled. */ From 5c3cc7229eeae61baab9748bc519c9f76ca1b66a Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Tue, 12 Aug 2025 15:18:33 -0600 Subject: [PATCH 39/74] fix: adapters --- packages/adapter-cloudflare/index.js | 3 +-- packages/adapter-netlify/index.js | 9 ++++++--- .../test/apps/basic/src/tracing.server.js | 1 + .../adapter-netlify/test/apps/basic/svelte.config.js | 5 +++++ packages/adapter-node/index.js | 4 +++- 5 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 packages/adapter-netlify/test/apps/basic/src/tracing.server.js diff --git a/packages/adapter-cloudflare/index.js b/packages/adapter-cloudflare/index.js index 647bb9cdda13..d7e5682226b4 100644 --- a/packages/adapter-cloudflare/index.js +++ b/packages/adapter-cloudflare/index.js @@ -116,8 +116,7 @@ export default function (options = {}) { if (builder.hasServerTracingFile()) { builder.trace({ entrypoint: worker_dest, - tracing: `${builder.getServerDirectory()}/tracing.server.js`, - tla: false + tracing: `${builder.getServerDirectory()}/tracing.server.js` }); } diff --git a/packages/adapter-netlify/index.js b/packages/adapter-netlify/index.js index 59d6db2bc84d..1ff8ee41dfcb 100644 --- a/packages/adapter-netlify/index.js +++ b/packages/adapter-netlify/index.js @@ -214,7 +214,6 @@ async function generate_edge_functions({ builder }) { builder.trace({ entrypoint: '.netlify/edge-functions/render.js', tracing: '.netlify/edge/tracing.server.js', - tla: false, start: '.netlify/edge/start.js' }); } @@ -300,7 +299,9 @@ function generate_lambda_functions({ builder, publish, split }) { entrypoint: `.netlify/functions-internal/${name}.mjs`, tracing: '.netlify/server/tracing.server.js', start: `.netlify/functions-start/${name}.start.mjs`, - exports: ['handler'] + module: { + exports: ['handler'] + } }); } @@ -322,7 +323,9 @@ function generate_lambda_functions({ builder, publish, split }) { entrypoint: `.netlify/functions-internal/${FUNCTION_PREFIX}render.mjs`, tracing: '.netlify/server/tracing.server.js', start: `.netlify/functions-start/${FUNCTION_PREFIX}render.start.mjs`, - exports: ['handler'] + module: { + exports: ['handler'] + } }); } diff --git a/packages/adapter-netlify/test/apps/basic/src/tracing.server.js b/packages/adapter-netlify/test/apps/basic/src/tracing.server.js new file mode 100644 index 000000000000..acc9022e1d64 --- /dev/null +++ b/packages/adapter-netlify/test/apps/basic/src/tracing.server.js @@ -0,0 +1 @@ +// this is just here to make sure the changes resulting from it work diff --git a/packages/adapter-netlify/test/apps/basic/svelte.config.js b/packages/adapter-netlify/test/apps/basic/svelte.config.js index 20cd2b3ff5b8..9cbf9ba19a31 100644 --- a/packages/adapter-netlify/test/apps/basic/svelte.config.js +++ b/packages/adapter-netlify/test/apps/basic/svelte.config.js @@ -4,6 +4,11 @@ import adapter from '../../../index.js'; const config = { kit: { adapter: adapter() + }, + experimental: { + tracing: { + serverFile: true + } } }; diff --git a/packages/adapter-node/index.js b/packages/adapter-node/index.js index 7ac3fcea1b06..024c402883c4 100644 --- a/packages/adapter-node/index.js +++ b/packages/adapter-node/index.js @@ -101,7 +101,9 @@ export default function (opts = {}) { builder.trace({ entrypoint: `${out}/index.js`, tracing: `${out}/server/tracing.server.js`, - exports: ['path', 'host', 'port', 'server'] + module: { + exports: ['path', 'host', 'port', 'server'] + } }); } }, From 8c804a60f3d9e1ed2792021352ce3e8147e6fadf Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Tue, 12 Aug 2025 15:32:29 -0600 Subject: [PATCH 40/74] fix event state --- packages/kit/src/exports/hooks/sequence.js | 1 - .../kit/src/exports/internal/event-state.js | 33 +++---- packages/kit/src/exports/internal/index.js | 2 +- packages/kit/src/runtime/server/respond.js | 89 ++++++++++--------- 4 files changed, 64 insertions(+), 61 deletions(-) diff --git a/packages/kit/src/exports/hooks/sequence.js b/packages/kit/src/exports/hooks/sequence.js index 34c3b9915c47..9ec5a8306722 100644 --- a/packages/kit/src/exports/hooks/sequence.js +++ b/packages/kit/src/exports/hooks/sequence.js @@ -89,7 +89,6 @@ export function sequence(...handlers) { function apply_handle(i, event, parent_options) { const handle = handlers[i]; - console.log('in sequence', get_event_state(event)); return get_event_state(event).tracing.record_span({ name: 'sveltekit.handle.sequenced.${i}', attributes: { diff --git a/packages/kit/src/exports/internal/event-state.js b/packages/kit/src/exports/internal/event-state.js index f519cddac3a3..3fb137522b73 100644 --- a/packages/kit/src/exports/internal/event-state.js +++ b/packages/kit/src/exports/internal/event-state.js @@ -1,7 +1,7 @@ /** @import { RequestEvent } from '@sveltejs/kit' */ /** @import { MaybePromise, PrerenderOptions, ServerHooks, SSROptions, SSRState, RecordSpan } from 'types' */ -export const EVENT_STATE = Symbol('sveltekit private event state'); +const EVENT_STATE = Symbol('sveltekit private event state'); /** * Internal state associated with the current `RequestEvent`, @@ -20,23 +20,24 @@ export const EVENT_STATE = Symbol('sveltekit private event state'); */ /** - * @param {SSRState} state - * @param {SSROptions} options - * @param {RecordSpan} record_span - * @returns {RequestEventState} + * @param {{ event: RequestEvent, state: SSRState, options: SSROptions, record_span: RecordSpan }} args + * @returns {RequestEvent} */ -export function create_event_state(state, options, record_span) { - return { - prerendering: state.prerendering, - transport: options.hooks.transport, - handleValidationError: options.hooks.handleValidationError, - // this is necessary to avoid importing `record_span` in `sequence`, which - // won't work because `record_span` depends on `otel`, which depends on - // being bundled through Vite. - tracing: { - record_span +export function add_event_state({ event, state, options, record_span }) { + Object.defineProperty(event, EVENT_STATE, { + value: { + prerendering: state.prerendering, + transport: options.hooks.transport, + handleValidationError: options.hooks.handleValidationError, + // this is necessary to avoid importing `record_span` in `sequence`, which + // won't work because `record_span` depends on `otel`, which depends on + // being bundled through Vite. + tracing: { + record_span + } } - }; + }); + return event; } /** diff --git a/packages/kit/src/exports/internal/index.js b/packages/kit/src/exports/internal/index.js index 3a66d6b6289c..0860df020333 100644 --- a/packages/kit/src/exports/internal/index.js +++ b/packages/kit/src/exports/internal/index.js @@ -64,7 +64,7 @@ export class ActionFailure { export { with_event, getRequestEvent } from './event.js'; -export { get_event_state, create_event_state, EVENT_STATE } from './event-state.js'; +export { get_event_state, add_event_state } from './event-state.js'; export { validate_remote_functions } from './remote-functions.js'; diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index 94b066463ffa..d071bbeb8f97 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -4,8 +4,7 @@ import { Redirect, SvelteKitError, with_event, - create_event_state, - EVENT_STATE, + add_event_state, merge_tracing } from '@sveltejs/kit/internal'; import { base, app_dir } from '__sveltekit/paths'; @@ -144,52 +143,56 @@ export async function internal_respond(request, options, manifest, state) { ); /** @type {import('@sveltejs/kit').RequestEvent} */ - const event = { - [EVENT_STATE]: create_event_state(state, options, record_span), - cookies, - // @ts-expect-error `fetch` needs to be created after the `event` itself - fetch: null, - getClientAddress: - state.getClientAddress || - (() => { - throw new Error( - `${__SVELTEKIT_ADAPTER_NAME__} does not specify getClientAddress. Please raise an issue` - ); - }), - locals: {}, - params: {}, - platform: state.platform, - request, - route: { id: null }, - setHeaders: (new_headers) => { - if (__SVELTEKIT_DEV__) { - validateHeaders(new_headers); - } - - for (const key in new_headers) { - const lower = key.toLowerCase(); - const value = new_headers[key]; - - if (lower === 'set-cookie') { + const event = add_event_state({ + state, + options, + record_span, + event: { + cookies, + // @ts-expect-error `fetch` needs to be created after the `event` itself + fetch: null, + getClientAddress: + state.getClientAddress || + (() => { throw new Error( - 'Use `event.cookies.set(name, value, options)` instead of `event.setHeaders` to set cookies' + `${__SVELTEKIT_ADAPTER_NAME__} does not specify getClientAddress. Please raise an issue` ); - } else if (lower in headers) { - throw new Error(`"${key}" header is already set`); - } else { - headers[lower] = value; + }), + locals: {}, + params: {}, + platform: state.platform, + request, + route: { id: null }, + setHeaders: (new_headers) => { + if (__SVELTEKIT_DEV__) { + validateHeaders(new_headers); + } + + for (const key in new_headers) { + const lower = key.toLowerCase(); + const value = new_headers[key]; - if (state.prerendering && lower === 'cache-control') { - state.prerendering.cache = /** @type {string} */ (value); + if (lower === 'set-cookie') { + throw new Error( + 'Use `event.cookies.set(name, value, options)` instead of `event.setHeaders` to set cookies' + ); + } else if (lower in headers) { + throw new Error(`"${key}" header is already set`); + } else { + headers[lower] = value; + + if (state.prerendering && lower === 'cache-control') { + state.prerendering.cache = /** @type {string} */ (value); + } } } - } - }, - url, - isDataRequest: is_data_request, - isSubRequest: state.depth > 0, - isRemoteRequest: !!remote_id - }; + }, + url, + isDataRequest: is_data_request, + isSubRequest: state.depth > 0, + isRemoteRequest: !!remote_id + } + }); event.fetch = create_fetch({ event, From 00eec4ad3a59b6e171372aee304299dacabf2902 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Tue, 12 Aug 2025 15:32:53 -0600 Subject: [PATCH 41/74] harder --- packages/kit/src/exports/internal/event-state.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/kit/src/exports/internal/event-state.js b/packages/kit/src/exports/internal/event-state.js index 3fb137522b73..d495c672a0a1 100644 --- a/packages/kit/src/exports/internal/event-state.js +++ b/packages/kit/src/exports/internal/event-state.js @@ -35,7 +35,8 @@ export function add_event_state({ event, state, options, record_span }) { tracing: { record_span } - } + }, + enumerable: false }); return event; } From 5660820ef1dc084ac8f632d22e6ec95d2961285c Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Tue, 12 Aug 2025 16:11:26 -0600 Subject: [PATCH 42/74] exit hell --- packages/kit/src/exports/internal/event-state.js | 16 ++++++++++++---- packages/kit/src/exports/internal/index.js | 9 ++++++--- .../kit/src/runtime/app/server/remote/shared.js | 13 ++++++++----- packages/kit/src/runtime/server/data/index.js | 4 ++-- packages/kit/src/runtime/server/respond.js | 7 ++++--- 5 files changed, 32 insertions(+), 17 deletions(-) diff --git a/packages/kit/src/exports/internal/event-state.js b/packages/kit/src/exports/internal/event-state.js index d495c672a0a1..b728f040acfb 100644 --- a/packages/kit/src/exports/internal/event-state.js +++ b/packages/kit/src/exports/internal/event-state.js @@ -24,7 +24,7 @@ const EVENT_STATE = Symbol('sveltekit private event state'); * @returns {RequestEvent} */ export function add_event_state({ event, state, options, record_span }) { - Object.defineProperty(event, EVENT_STATE, { + return Object.defineProperty(event, EVENT_STATE, { value: { prerendering: state.prerendering, transport: options.hooks.transport, @@ -35,10 +35,18 @@ export function add_event_state({ event, state, options, record_span }) { tracing: { record_span } - }, - enumerable: false + } + }); +} + +/** + * @param {RequestEvent} event + * @param {RequestEvent} target + */ +export function copy_event_state(event, target) { + return Object.defineProperty(target, EVENT_STATE, { + value: get_event_state(event) }); - return event; } /** diff --git a/packages/kit/src/exports/internal/index.js b/packages/kit/src/exports/internal/index.js index 0860df020333..45882e101107 100644 --- a/packages/kit/src/exports/internal/index.js +++ b/packages/kit/src/exports/internal/index.js @@ -1,3 +1,5 @@ +import { copy_event_state } from './event-state.js'; + export class HttpError { /** * @param {number} status @@ -64,7 +66,7 @@ export class ActionFailure { export { with_event, getRequestEvent } from './event.js'; -export { get_event_state, add_event_state } from './event-state.js'; +export { get_event_state, add_event_state, copy_event_state } from './event-state.js'; export { validate_remote_functions } from './remote-functions.js'; @@ -75,11 +77,12 @@ export { validate_remote_functions } from './remote-functions.js'; * @returns {T} */ export function merge_tracing(event_like, current) { - return { + // @ts-expect-error + return copy_event_state(event_like, { ...event_like, tracing: { ...event_like.tracing, current } - }; + }); } diff --git a/packages/kit/src/runtime/app/server/remote/shared.js b/packages/kit/src/runtime/app/server/remote/shared.js index c0155c00d211..43bbc80638f4 100644 --- a/packages/kit/src/runtime/app/server/remote/shared.js +++ b/packages/kit/src/runtime/app/server/remote/shared.js @@ -2,7 +2,12 @@ /** @import { ServerHooks, MaybePromise } from 'types' */ import { parse } from 'devalue'; import { error } from '@sveltejs/kit'; -import { getRequestEvent, with_event, get_event_state } from '@sveltejs/kit/internal'; +import { + getRequestEvent, + with_event, + get_event_state, + copy_event_state +} from '@sveltejs/kit/internal'; import { create_remote_cache_key, stringify_remote_arg } from '../../../shared.js'; /** @@ -110,10 +115,8 @@ export function parse_remote_response(data, transport) { */ export async function run_remote_function(event, allow_cookies, arg, validate, fn) { /** @type {RequestEvent} */ - const cleansed = { + const cleansed = copy_event_state(event, { ...event, - // @ts-expect-error this isn't part of the public `RequestEvent` type - [EVENT_STATE]: event[EVENT_STATE], setHeaders: () => { throw new Error('setHeaders is not allowed in remote functions'); }, @@ -144,7 +147,7 @@ export async function run_remote_function(event, allow_cookies, arg, validate, f }, route: { id: null }, url: new URL(event.url.origin) - }; + }); // In two parts, each with_event, so that runtimes without async local storage can still get the event at the start of the function const validated = await with_event(cleansed, () => validate(arg)); diff --git a/packages/kit/src/runtime/server/data/index.js b/packages/kit/src/runtime/server/data/index.js index b87b370bfc73..7e2e75aeb820 100644 --- a/packages/kit/src/runtime/server/data/index.js +++ b/packages/kit/src/runtime/server/data/index.js @@ -1,5 +1,5 @@ import { text } from '@sveltejs/kit'; -import { HttpError, SvelteKitError, Redirect } from '@sveltejs/kit/internal'; +import { HttpError, SvelteKitError, Redirect, copy_event_state } from '@sveltejs/kit/internal'; import { normalize_error } from '../../../utils/error.js'; import { once } from '../../../utils/functions.js'; import { load_server_data } from '../page/load_data.js'; @@ -44,7 +44,7 @@ export async function render_data( const url = new URL(event.url); url.pathname = normalize_path(url.pathname, trailing_slash); - const new_event = { ...event, url }; + const new_event = copy_event_state(event, { ...event, url }); const functions = node_ids.map((n, i) => { return once(async () => { diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index d071bbeb8f97..20326651d509 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -5,7 +5,8 @@ import { SvelteKitError, with_event, add_event_state, - merge_tracing + merge_tracing, + copy_event_state } from '@sveltejs/kit/internal'; import { base, app_dir } from '__sveltekit/paths'; import { is_endpoint_request, render_endpoint } from './endpoint.js'; @@ -401,14 +402,14 @@ export async function internal_respond(request, options, manifest, state) { 'sveltekit.is_sub_request': event.isSubRequest }, fn: async (root_span) => { - const traced_event = { + const traced_event = copy_event_state(event, { ...event, tracing: { enabled: __SVELTEKIT_SERVER_TRACING_ENABLED__, root: root_span, current: root_span } - }; + }); return await with_event(traced_event, () => options.hooks.handle({ event: traced_event, From 3a8b5ac5f94ef43decd27c6e8be9639b1307db76 Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Tue, 12 Aug 2025 16:19:02 -0600 Subject: [PATCH 43/74] Update packages/kit/src/exports/vite/utils.js Co-authored-by: Rich Harris --- packages/kit/src/exports/vite/utils.js | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/kit/src/exports/vite/utils.js b/packages/kit/src/exports/vite/utils.js index ce2a7c0ae6d2..e2017a53d68e 100644 --- a/packages/kit/src/exports/vite/utils.js +++ b/packages/kit/src/exports/vite/utils.js @@ -197,17 +197,13 @@ export const strip_virtual_prefix = /** @param {string} id */ (id) => id.replace * @returns {never} */ export function error_for_missing_config(feature_name, path, value) { - const parts = path.split('.'); const hole = '__HOLE__'; - /** @param {number} n */ - const indent = (n) => ' '.repeat(n); - const result = parts.reduce((acc, part, i) => { - if (i === parts.length - 1) { - return acc.replace(hole, `${indent(i)}${part}: ${value}`); - } else { - return acc.replace(hole, `${indent(i)}${part}: {\n${hole}\n${indent(i)}}`); - } + const result = path.split('.').reduce((acc, part, i, parts) => { + const indent = ' '.repeat(i); + const rhs = i === parts.length - 1 ? value : `{\n${hole}\n${indent}}`; + + return acc.replace(hole, `${indent}${part}: ${rhs}`); }, hole); throw new Error( From 8e0ba7a69a46c2bf68301ad536f1c7feee3cf79d Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Tue, 12 Aug 2025 16:23:27 -0600 Subject: [PATCH 44/74] address feedback --- packages/kit/src/core/adapt/builder.js | 24 ++++++++---------------- packages/kit/src/exports/vite/index.js | 6 +++--- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/packages/kit/src/core/adapt/builder.js b/packages/kit/src/core/adapt/builder.js index e4993fecdc0c..a73581699d21 100644 --- a/packages/kit/src/core/adapt/builder.js +++ b/packages/kit/src/core/adapt/builder.js @@ -323,12 +323,12 @@ function create_tracing_facade({ tracing, start, exports }) { for (const name of exports.filter((name) => reserved.has(name))) { /* - you can do evil things like `export { c as class }`. - in order to import these, you need to alias them, and then un-alias them when re-exporting - this map will allow us to generate the following: - import { class as _1 } from 'entrypoint'; - export { _1 as class }; - */ + * you can do evil things like `export { c as class }`. + * in order to import these, you need to alias them, and then un-alias them when re-exporting + * this map will allow us to generate the following: + * import { class as _1 } from 'entrypoint'; + * export { _1 as class }; + */ let alias = `_${alias_index++}`; while (exports.includes(alias)) { alias = `_${alias_index++}`; @@ -344,23 +344,15 @@ function create_tracing_facade({ tracing, start, exports }) { const alias = aliases.get(name); if (alias) { import_statements.push(`${name}: ${alias}`); - - if (name !== 'default') { - export_statements.push(`${alias} as ${name}`); - } + export_statements.push(`${alias} as ${name}`); } else { import_statements.push(`${name}`); - - if (name !== 'default') { - export_statements.push(`${name}`); - } + export_statements.push(`${name}`); } } - const default_alias = aliases.get('default'); const entrypoint_facade = [ `const { ${import_statements.join(', ')} } = await import('./${start}');`, - default_alias ? `export default ${default_alias};` : '', export_statements.length > 0 ? `export { ${export_statements.join(', ')} };` : '' ] .filter(Boolean) diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index ac300d473337..cb990eb5731f 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -338,7 +338,7 @@ async function kit({ svelte_config }) { __SVELTEKIT_DEV__: 'false', __SVELTEKIT_EMBEDDED__: s(kit.embedded), __SVELTEKIT_EXPERIMENTAL__REMOTE_FUNCTIONS__: s(kit.experimental.remoteFunctions), - __SVELTEKIT_CLIENT_ROUTING__: kit.router.resolution === 'client' ? 'true' : 'false', + __SVELTEKIT_CLIENT_ROUTING__: s(kit.router.resolution === 'client'), __SVELTEKIT_SERVER_TRACING_ENABLED__: s(kit.experimental.tracing.server), __SVELTEKIT_PAYLOAD__: new_config.build.ssr ? '{}' @@ -354,8 +354,8 @@ async function kit({ svelte_config }) { __SVELTEKIT_DEV__: 'true', __SVELTEKIT_EMBEDDED__: s(kit.embedded), __SVELTEKIT_EXPERIMENTAL__REMOTE_FUNCTIONS__: s(kit.experimental.remoteFunctions), - __SVELTEKIT_CLIENT_ROUTING__: kit.router.resolution === 'client' ? 'true' : 'false', - __SVELTEKIT_SERVER_TRACING_ENABLED__: kit.experimental.tracing.server ? 'true' : 'false', + __SVELTEKIT_CLIENT_ROUTING__: s(kit.router.resolution === 'client'), + __SVELTEKIT_SERVER_TRACING_ENABLED__: s(kit.experimental.tracing.server), __SVELTEKIT_PAYLOAD__: 'globalThis.__sveltekit_dev' }; From e65a25e8371c104fa857263da22b57811fd50d09 Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Tue, 12 Aug 2025 16:23:54 -0600 Subject: [PATCH 45/74] Update documentation/docs/30-advanced/68-observability.md Co-authored-by: Rich Harris --- documentation/docs/30-advanced/68-observability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/30-advanced/68-observability.md b/documentation/docs/30-advanced/68-observability.md index b2e8d6a0eb76..84e57c07dab6 100644 --- a/documentation/docs/30-advanced/68-observability.md +++ b/documentation/docs/30-advanced/68-observability.md @@ -35,7 +35,7 @@ export default { > [!NOTE] Tracing -- and more significantly, tracing instrumentation -- can have a nontrivial overhead. Before you go all-in on tracing, consider whether or not you really need it, or if it might be more appropriate to turn it on in development and preview environments only. -## Development Quickstart +## Development quickstart To view your first trace, you'll need to set up a local collector. We'll use [Jaeger](https://www.jaegertracing.io/docs/getting-started/) in this example, as they provide an easy-to-use quickstart command. Once your collector is running locally: From 06486db2b91a4ac0e5d992f98a93a562c4714a38 Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Tue, 12 Aug 2025 16:24:07 -0600 Subject: [PATCH 46/74] Update documentation/docs/30-advanced/68-observability.md Co-authored-by: Rich Harris --- documentation/docs/30-advanced/68-observability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/30-advanced/68-observability.md b/documentation/docs/30-advanced/68-observability.md index 84e57c07dab6..7bd8b53ccd16 100644 --- a/documentation/docs/30-advanced/68-observability.md +++ b/documentation/docs/30-advanced/68-observability.md @@ -15,7 +15,7 @@ Sometimes, you may need to observe how your application is behaving in order to - Form actions - Remote functions -Just telling SvelteKit to emit spans won't get you far, though -- you need to actually collect them somewhere to be able to view them. SvelteKit provides `src/tracing.server.ts` as a place to write your tracing setup and instrumentation code. It's guaranteed to be run prior to your application code being imported. +Just telling SvelteKit to emit spans won't get you far, though -- you need to actually collect them somewhere to be able to view them. SvelteKit provides `src/tracing.server.ts` as a place to write your tracing setup and instrumentation code. It's guaranteed to be run prior to your application code being imported, providing your deployment platform supports it and your adapter is aware of it. To enable both of these features, add the following to your `svelte.config.js`: From 512538e261cf01d06a5de279fa1cbfad7c738829 Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Tue, 12 Aug 2025 16:24:25 -0600 Subject: [PATCH 47/74] Update documentation/docs/30-advanced/68-observability.md Co-authored-by: Rich Harris --- documentation/docs/30-advanced/68-observability.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/docs/30-advanced/68-observability.md b/documentation/docs/30-advanced/68-observability.md index 7bd8b53ccd16..4d4ee23801f2 100644 --- a/documentation/docs/30-advanced/68-observability.md +++ b/documentation/docs/30-advanced/68-observability.md @@ -12,8 +12,8 @@ Sometimes, you may need to observe how your application is behaving in order to - `handle` hook (`sequence`d `handle` functions will show up as children of each other and the root handle hook) - `load` functions (includes univeral `load` functions when they're run on the server) -- Form actions -- Remote functions +- [Form actions](form-actions) +- [Remote functions](remote-functions) Just telling SvelteKit to emit spans won't get you far, though -- you need to actually collect them somewhere to be able to view them. SvelteKit provides `src/tracing.server.ts` as a place to write your tracing setup and instrumentation code. It's guaranteed to be run prior to your application code being imported, providing your deployment platform supports it and your adapter is aware of it. From 4b09980e9b9b26b44e65159894f79b1858595e59 Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Tue, 12 Aug 2025 16:24:34 -0600 Subject: [PATCH 48/74] Update documentation/docs/30-advanced/68-observability.md Co-authored-by: Rich Harris --- documentation/docs/30-advanced/68-observability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/30-advanced/68-observability.md b/documentation/docs/30-advanced/68-observability.md index 4d4ee23801f2..2d86dde9ede7 100644 --- a/documentation/docs/30-advanced/68-observability.md +++ b/documentation/docs/30-advanced/68-observability.md @@ -11,7 +11,7 @@ title: Observability Sometimes, you may need to observe how your application is behaving in order to improve performance or find the root cause of a pesky bug. To help with this, SvelteKit can emit server-side [OpenTelemetry](https://opentelemetry.io) spans for the following: - `handle` hook (`sequence`d `handle` functions will show up as children of each other and the root handle hook) -- `load` functions (includes univeral `load` functions when they're run on the server) +- [`load`](load) functions (includes universal `load` functions when they're run on the server) - [Form actions](form-actions) - [Remote functions](remote-functions) From a111b7d19a2d24d6f3e0973404aef46f5fee6d60 Mon Sep 17 00:00:00 2001 From: Elliott Johnson Date: Tue, 12 Aug 2025 16:24:44 -0600 Subject: [PATCH 49/74] Update documentation/docs/30-advanced/68-observability.md Co-authored-by: Rich Harris --- documentation/docs/30-advanced/68-observability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/30-advanced/68-observability.md b/documentation/docs/30-advanced/68-observability.md index 2d86dde9ede7..1d38b42de821 100644 --- a/documentation/docs/30-advanced/68-observability.md +++ b/documentation/docs/30-advanced/68-observability.md @@ -10,7 +10,7 @@ title: Observability Sometimes, you may need to observe how your application is behaving in order to improve performance or find the root cause of a pesky bug. To help with this, SvelteKit can emit server-side [OpenTelemetry](https://opentelemetry.io) spans for the following: -- `handle` hook (`sequence`d `handle` functions will show up as children of each other and the root handle hook) +- [`handle`](hooks#Server-hooks-handle) hook (`handle` functions running in a [`sequence`](@sveltejs-kit-hooks#sequence) will show up as children of each other and the root handle hook) - [`load`](load) functions (includes universal `load` functions when they're run on the server) - [Form actions](form-actions) - [Remote functions](remote-functions) From 3188b73c13a32a1e42816d3532253c1974b51c89 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 12 Aug 2025 19:46:34 -0400 Subject: [PATCH 50/74] we can't use here... long story but it breaks the docs --- packages/kit/src/exports/public.d.ts | 2 +- packages/kit/types/index.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index dd7bb559b9d9..2fc5a36d6583 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -212,7 +212,7 @@ export interface Builder { * Caveats: * - "Live exports" will not work. If your adapter uses live exports, your users will need to manually import the server instrumentation on startup. * - If `tla` is `false`, OTEL auto-instrumentation may not work properly. Use it if your environment supports it. - * - Use {@link hasServerTracingFile} to check if the user has a server tracing file; if they don't, you shouldn't do this. + * - Use `hasServerTracingFile` to check if the user has a server tracing file; if they don't, you shouldn't do this. * * @param options an object containing the following properties: * @param options.entrypoint the path to the entrypoint to trace. diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 0dc49915654d..f7be510fc5bf 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -189,7 +189,7 @@ declare module '@sveltejs/kit' { * Caveats: * - "Live exports" will not work. If your adapter uses live exports, your users will need to manually import the server instrumentation on startup. * - If `tla` is `false`, OTEL auto-instrumentation may not work properly. Use it if your environment supports it. - * - Use {@link hasServerTracingFile} to check if the user has a server tracing file; if they don't, you shouldn't do this. + * - Use `hasServerTracingFile` to check if the user has a server tracing file; if they don't, you shouldn't do this. * * @param options an object containing the following properties: * @param options.entrypoint the path to the entrypoint to trace. From 268cd82d17fa5548b30df6f58f1fd113c3300c35 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Tue, 12 Aug 2025 18:00:10 -0600 Subject: [PATCH 51/74] destroy event-state --- packages/kit/src/exports/hooks/sequence.js | 13 +- .../kit/src/exports/hooks/sequence.spec.js | 41 ++++-- .../kit/src/exports/internal/event-state.js | 60 --------- packages/kit/src/exports/internal/event.js | 32 +++-- packages/kit/src/exports/internal/index.js | 16 +-- .../src/runtime/app/server/remote/command.js | 8 +- .../kit/src/runtime/app/server/remote/form.js | 11 +- .../runtime/app/server/remote/prerender.js | 11 +- .../src/runtime/app/server/remote/query.js | 13 +- .../src/runtime/app/server/remote/shared.js | 28 ++-- packages/kit/src/runtime/server/data/index.js | 19 ++- packages/kit/src/runtime/server/endpoint.js | 7 +- .../kit/src/runtime/server/page/actions.js | 29 +++-- packages/kit/src/runtime/server/page/index.js | 27 +++- .../kit/src/runtime/server/page/load_data.js | 11 +- .../kit/src/runtime/server/page/render.js | 21 ++- .../runtime/server/page/respond_with_error.js | 9 +- packages/kit/src/runtime/server/remote.js | 46 ++++--- packages/kit/src/runtime/server/respond.js | 120 ++++++++++-------- packages/kit/src/runtime/server/utils.js | 13 +- packages/kit/src/types/internal.d.ts | 21 +++ .../kit/test/apps/basics/src/hooks.server.js | 3 +- .../kit/test/apps/basics/test/server.test.js | 36 ++---- 23 files changed, 315 insertions(+), 280 deletions(-) delete mode 100644 packages/kit/src/exports/internal/event-state.js diff --git a/packages/kit/src/exports/hooks/sequence.js b/packages/kit/src/exports/hooks/sequence.js index 9ec5a8306722..fb152f187422 100644 --- a/packages/kit/src/exports/hooks/sequence.js +++ b/packages/kit/src/exports/hooks/sequence.js @@ -1,6 +1,6 @@ /** @import { Handle, RequestEvent, ResolveOptions } from '@sveltejs/kit' */ /** @import { MaybePromise } from 'types' */ -import { with_event, get_event_state, merge_tracing } from '@sveltejs/kit/internal'; +import { merge_tracing, get_request_store, with_request_store } from '@sveltejs/kit/internal'; /** * A helper function for sequencing multiple `handle` calls in a middleware-like manner. @@ -87,16 +87,15 @@ export function sequence(...handlers) { * @returns {MaybePromise} */ function apply_handle(i, event, parent_options) { + const store = get_request_store(); const handle = handlers[i]; - return get_event_state(event).tracing.record_span({ - name: 'sveltekit.handle.sequenced.${i}', - attributes: { - 'sveltekit.handle.sequenced.name': handle.name - }, + return store.state.tracing.record_span({ + name: `sveltekit.handle.sequenced.${handle.name ? handle.name : i}`, + attributes: {}, fn: async (current) => { const traced_event = merge_tracing(event, current); - return await with_event(traced_event, () => + return await with_request_store({ event: traced_event, state: store.state }, () => handle({ event: traced_event, resolve: (event, options) => { diff --git a/packages/kit/src/exports/hooks/sequence.spec.js b/packages/kit/src/exports/hooks/sequence.spec.js index 5e2fe5d4c66d..293f15155999 100644 --- a/packages/kit/src/exports/hooks/sequence.spec.js +++ b/packages/kit/src/exports/hooks/sequence.spec.js @@ -1,21 +1,36 @@ -import { assert, expect, test } from 'vitest'; +/** @import { RequestEvent } from '@sveltejs/kit' */ +/** @import { RequestState } from 'types' */ +import { assert, expect, test, vi } from 'vitest'; import { sequence } from './sequence.js'; import { installPolyfills } from '../node/polyfills.js'; -import { add_event_state } from '@sveltejs/kit/internal'; +import { noop_span } from '../../runtime/telemetry/noop.js'; + +const dummy_event = vi.hoisted( + () => + /** @type {RequestEvent} */ ({ + tracing: { + root: {} + } + }) +); + +vi.mock(import('@sveltejs/kit/internal'), async (actualPromise) => { + const actual = await actualPromise(); + return { + ...actual, + get_request_store: () => ({ + event: dummy_event, + state: /** @type {RequestState} */ ({ + tracing: { + record_span: ({ fn }) => fn(noop_span) + } + }) + }) + }; +}); installPolyfills(); -const dummy_event = add_event_state({ - // @ts-expect-error - record_span: ({ fn }) => fn(), - event: { - tracing: { - // @ts-expect-error - root: {} - } - } -}); - test('applies handlers in sequence', async () => { /** @type {string[]} */ const order = []; diff --git a/packages/kit/src/exports/internal/event-state.js b/packages/kit/src/exports/internal/event-state.js deleted file mode 100644 index b728f040acfb..000000000000 --- a/packages/kit/src/exports/internal/event-state.js +++ /dev/null @@ -1,60 +0,0 @@ -/** @import { RequestEvent } from '@sveltejs/kit' */ -/** @import { MaybePromise, PrerenderOptions, ServerHooks, SSROptions, SSRState, RecordSpan } from 'types' */ - -const EVENT_STATE = Symbol('sveltekit private event state'); - -/** - * Internal state associated with the current `RequestEvent`, - * used for tracking things like remote function calls - * @typedef {{ - * prerendering: PrerenderOptions | undefined - * transport: ServerHooks['transport']; - * handleValidationError: ServerHooks['handleValidationError']; - * tracing: { - * record_span: RecordSpan - * } - * form_instances?: Map; - * remote_data?: Record>; - * refreshes?: Record; - * }} RequestEventState - */ - -/** - * @param {{ event: RequestEvent, state: SSRState, options: SSROptions, record_span: RecordSpan }} args - * @returns {RequestEvent} - */ -export function add_event_state({ event, state, options, record_span }) { - return Object.defineProperty(event, EVENT_STATE, { - value: { - prerendering: state.prerendering, - transport: options.hooks.transport, - handleValidationError: options.hooks.handleValidationError, - // this is necessary to avoid importing `record_span` in `sequence`, which - // won't work because `record_span` depends on `otel`, which depends on - // being bundled through Vite. - tracing: { - record_span - } - } - }); -} - -/** - * @param {RequestEvent} event - * @param {RequestEvent} target - */ -export function copy_event_state(event, target) { - return Object.defineProperty(target, EVENT_STATE, { - value: get_event_state(event) - }); -} - -/** - * Returns internal state associated with the current `RequestEvent` - * @param {RequestEvent} event - * @returns {RequestEventState} - */ -export function get_event_state(event) { - // @ts-expect-error the symbol isn't exposed on the public `RequestEvent` type - return event[EVENT_STATE]; -} diff --git a/packages/kit/src/exports/internal/event.js b/packages/kit/src/exports/internal/event.js index dc3c2a04da6e..f04ed91f13f2 100644 --- a/packages/kit/src/exports/internal/event.js +++ b/packages/kit/src/exports/internal/event.js @@ -1,9 +1,9 @@ -/** @import { RequestEvent } from '@sveltejs/kit' */ +/** @import { RequestStore } from 'types' */ -/** @type {RequestEvent | null} */ -let request_event = null; +/** @type {RequestStore | null} */ +let sync_store = null; -/** @type {import('node:async_hooks').AsyncLocalStorage | null} */ +/** @type {import('node:async_hooks').AsyncLocalStorage | null} */ let als; import('node:async_hooks') @@ -21,7 +21,7 @@ import('node:async_hooks') * @since 2.20.0 */ export function getRequestEvent() { - const event = request_event ?? als?.getStore(); + const event = try_get_request_store()?.event; if (!event) { let message = @@ -38,16 +38,28 @@ export function getRequestEvent() { return event; } +export function get_request_store() { + const result = try_get_request_store(); + if (!result) { + throw new Error('Could not get the request store. This is an internal error.'); + } + return result; +} + +export function try_get_request_store() { + return sync_store ?? als?.getStore() ?? null; +} + /** * @template T - * @param {RequestEvent | null} event + * @param {RequestStore | null} store * @param {() => T} fn */ -export function with_event(event, fn) { +export function with_request_store(store, fn) { try { - request_event = event; - return als ? als.run(event, fn) : fn(); + sync_store = store; + return als ? als.run(store, fn) : fn(); } finally { - request_event = null; + sync_store = null; } } diff --git a/packages/kit/src/exports/internal/index.js b/packages/kit/src/exports/internal/index.js index 45882e101107..67e9c8e0b0b5 100644 --- a/packages/kit/src/exports/internal/index.js +++ b/packages/kit/src/exports/internal/index.js @@ -1,5 +1,3 @@ -import { copy_event_state } from './event-state.js'; - export class HttpError { /** * @param {number} status @@ -64,9 +62,12 @@ export class ActionFailure { } } -export { with_event, getRequestEvent } from './event.js'; - -export { get_event_state, add_event_state, copy_event_state } from './event-state.js'; +export { + with_request_store, + getRequestEvent, + get_request_store, + try_get_request_store +} from './event.js'; export { validate_remote_functions } from './remote-functions.js'; @@ -77,12 +78,11 @@ export { validate_remote_functions } from './remote-functions.js'; * @returns {T} */ export function merge_tracing(event_like, current) { - // @ts-expect-error - return copy_event_state(event_like, { + return { ...event_like, tracing: { ...event_like.tracing, current } - }); + }; } diff --git a/packages/kit/src/runtime/app/server/remote/command.js b/packages/kit/src/runtime/app/server/remote/command.js index a3ff9c173a83..e96025e802b2 100644 --- a/packages/kit/src/runtime/app/server/remote/command.js +++ b/packages/kit/src/runtime/app/server/remote/command.js @@ -1,7 +1,7 @@ /** @import { RemoteCommand } from '@sveltejs/kit' */ /** @import { RemoteInfo, MaybePromise } from 'types' */ /** @import { StandardSchemaV1 } from '@standard-schema/spec' */ -import { getRequestEvent, get_event_state } from '@sveltejs/kit/internal'; +import { get_request_store } from '@sveltejs/kit/internal'; import { check_experimental, create_validator, run_remote_function } from './shared.js'; /** @@ -64,7 +64,7 @@ export function command(validate_or_fn, maybe_fn) { /** @type {RemoteCommand & { __: RemoteInfo }} */ const wrapper = (arg) => { - const event = getRequestEvent(); + const { event, state } = get_request_store(); if (!event.isRemoteRequest) { throw new Error( @@ -72,9 +72,9 @@ export function command(validate_or_fn, maybe_fn) { ); } - get_event_state(event).refreshes ??= {}; + state.refreshes ??= {}; - const promise = Promise.resolve(run_remote_function(event, true, arg, validate, fn)); + const promise = Promise.resolve(run_remote_function(event, state, true, arg, validate, fn)); // @ts-expect-error promise.updates = () => { diff --git a/packages/kit/src/runtime/app/server/remote/form.js b/packages/kit/src/runtime/app/server/remote/form.js index c5a288cc30c6..caa1f3120ddc 100644 --- a/packages/kit/src/runtime/app/server/remote/form.js +++ b/packages/kit/src/runtime/app/server/remote/form.js @@ -1,6 +1,6 @@ /** @import { RemoteForm } from '@sveltejs/kit' */ /** @import { RemoteInfo, MaybePromise } from 'types' */ -import { getRequestEvent, get_event_state } from '@sveltejs/kit/internal'; +import { get_request_store } from '@sveltejs/kit/internal'; import { check_experimental, run_remote_function } from './shared.js'; /** @@ -56,12 +56,11 @@ export function form(fn) { id: '', /** @param {FormData} form_data */ fn: async (form_data) => { - const event = getRequestEvent(); - const state = get_event_state(event); + const { event, state } = get_request_store(); state.refreshes ??= {}; - const result = await run_remote_function(event, true, form_data, (d) => d, fn); + const result = await run_remote_function(event, state, true, form_data, (d) => d, fn); // We don't need to care about args or deduplicating calls, because uneval results are only relevant in full page reloads // where only one form submission is active at the same time @@ -88,7 +87,7 @@ export function form(fn) { Object.defineProperty(instance, 'result', { get() { try { - const { remote_data } = get_event_state(getRequestEvent()); + const { remote_data } = get_request_store().state; return remote_data?.[__.id]; } catch { return undefined; @@ -110,7 +109,7 @@ export function form(fn) { Object.defineProperty(instance, 'for', { /** @type {RemoteForm['for']} */ value: (key) => { - const state = get_event_state(getRequestEvent()); + const { state } = get_request_store(); let instance = (state.form_instances ??= new Map()).get(key); if (!instance) { diff --git a/packages/kit/src/runtime/app/server/remote/prerender.js b/packages/kit/src/runtime/app/server/remote/prerender.js index 5de0a936b907..46489e7a0555 100644 --- a/packages/kit/src/runtime/app/server/remote/prerender.js +++ b/packages/kit/src/runtime/app/server/remote/prerender.js @@ -3,7 +3,7 @@ /** @import { StandardSchemaV1 } from '@standard-schema/spec' */ import { error, json } from '@sveltejs/kit'; import { DEV } from 'esm-env'; -import { getRequestEvent, get_event_state } from '@sveltejs/kit/internal'; +import { get_request_store } from '@sveltejs/kit/internal'; import { create_remote_cache_key, stringify, stringify_remote_arg } from '../../../shared.js'; import { app_dir, base } from '__sveltekit/paths'; import { @@ -92,15 +92,14 @@ export function prerender(validate_or_fn, fn_or_options, maybe_options) { const wrapper = (arg) => { /** @type {Promise & Partial>} */ const promise = (async () => { - const event = getRequestEvent(); - const state = get_event_state(event); + const { event, state } = get_request_store(); const payload = stringify_remote_arg(arg, state.transport); const id = __.id; const url = `${base}/${app_dir}/remote/${id}${payload ? `/${payload}` : ''}`; if (!state.prerendering && !DEV && !event.isRemoteRequest) { try { - return await get_response(id, arg, event, async () => { + return await get_response(id, arg, state, async () => { // TODO adapters can provide prerendered data more efficiently than // fetching from the public internet const response = await fetch(new URL(url, event.url.origin).href); @@ -129,8 +128,8 @@ export function prerender(validate_or_fn, fn_or_options, maybe_options) { return /** @type {Promise} */ (state.prerendering.remote_responses.get(url)); } - const promise = get_response(id, arg, event, () => - run_remote_function(event, false, arg, validate, fn) + const promise = get_response(id, arg, state, () => + run_remote_function(event, state, false, arg, validate, fn) ); if (state.prerendering) { diff --git a/packages/kit/src/runtime/app/server/remote/query.js b/packages/kit/src/runtime/app/server/remote/query.js index 2d77cb8e20a0..4fb38995916a 100644 --- a/packages/kit/src/runtime/app/server/remote/query.js +++ b/packages/kit/src/runtime/app/server/remote/query.js @@ -1,7 +1,7 @@ /** @import { RemoteQuery, RemoteQueryFunction } from '@sveltejs/kit' */ /** @import { RemoteInfo, MaybePromise } from 'types' */ /** @import { StandardSchemaV1 } from '@standard-schema/spec' */ -import { getRequestEvent, get_event_state } from '@sveltejs/kit/internal'; +import { get_request_store } from '@sveltejs/kit/internal'; import { create_remote_cache_key, stringify_remote_arg } from '../../../shared.js'; import { prerendering } from '__sveltekit/environment'; import { @@ -77,19 +77,18 @@ export function query(validate_or_fn, maybe_fn) { ); } - const event = getRequestEvent(); + const { event, state } = get_request_store(); /** @type {Promise & Partial>} */ - const promise = get_response(__.id, arg, event, () => - run_remote_function(event, false, arg, validate, fn) + const promise = get_response(__.id, arg, state, () => + run_remote_function(event, state, false, arg, validate, fn) ); promise.catch(() => {}); promise.refresh = async () => { - const event = getRequestEvent(); - const state = get_event_state(event); - const refreshes = state?.refreshes; + const { state } = get_request_store(); + const refreshes = state.refreshes; if (!refreshes) { throw new Error( diff --git a/packages/kit/src/runtime/app/server/remote/shared.js b/packages/kit/src/runtime/app/server/remote/shared.js index 43bbc80638f4..e030b1ee7dcd 100644 --- a/packages/kit/src/runtime/app/server/remote/shared.js +++ b/packages/kit/src/runtime/app/server/remote/shared.js @@ -1,13 +1,8 @@ /** @import { RequestEvent } from '@sveltejs/kit' */ -/** @import { ServerHooks, MaybePromise } from 'types' */ +/** @import { ServerHooks, MaybePromise, RequestState } from 'types' */ import { parse } from 'devalue'; import { error } from '@sveltejs/kit'; -import { - getRequestEvent, - with_event, - get_event_state, - copy_event_state -} from '@sveltejs/kit/internal'; +import { with_request_store, get_request_store } from '@sveltejs/kit/internal'; import { create_remote_cache_key, stringify_remote_arg } from '../../../shared.js'; /** @@ -34,8 +29,7 @@ export function create_validator(validate_or_fn, maybe_fn) { if ('~standard' in validate_or_fn) { return async (arg) => { // Get event before async validation to ensure it's available in server environments without AsyncLocalStorage, too - const event = getRequestEvent(); - const state = get_event_state(event); + const { event, state } = get_request_store(); const validate = validate_or_fn['~standard'].validate; const result = await validate(arg); @@ -70,12 +64,11 @@ export function create_validator(validate_or_fn, maybe_fn) { * @template {MaybePromise} T * @param {string} id * @param {any} arg - * @param {RequestEvent} event + * @param {RequestState} state * @param {() => Promise} get_result * @returns {Promise} */ -export function get_response(id, arg, event, get_result) { - const state = get_event_state(event); +export function get_response(id, arg, state, get_result) { const cache_key = create_remote_cache_key(id, stringify_remote_arg(arg, state.transport)); return ((state.remote_data ??= {})[cache_key] ??= get_result()); @@ -108,14 +101,15 @@ export function parse_remote_response(data, transport) { * Like `with_event` but removes things from `event` you cannot see/call in remote functions, such as `setHeaders`. * @template T * @param {RequestEvent} event + * @param {RequestState} state * @param {boolean} allow_cookies * @param {any} arg * @param {(arg: any) => any} validate * @param {(arg?: any) => T} fn */ -export async function run_remote_function(event, allow_cookies, arg, validate, fn) { +export async function run_remote_function(event, state, allow_cookies, arg, validate, fn) { /** @type {RequestEvent} */ - const cleansed = copy_event_state(event, { + const cleansed = { ...event, setHeaders: () => { throw new Error('setHeaders is not allowed in remote functions'); @@ -147,9 +141,9 @@ export async function run_remote_function(event, allow_cookies, arg, validate, f }, route: { id: null }, url: new URL(event.url.origin) - }); + }; // In two parts, each with_event, so that runtimes without async local storage can still get the event at the start of the function - const validated = await with_event(cleansed, () => validate(arg)); - return with_event(cleansed, () => fn(validated)); + const validated = await with_request_store({ event: cleansed, state }, () => validate(arg)); + return with_request_store({ event: cleansed, state }, () => fn(validated)); } diff --git a/packages/kit/src/runtime/server/data/index.js b/packages/kit/src/runtime/server/data/index.js index 7e2e75aeb820..37fc409ab42d 100644 --- a/packages/kit/src/runtime/server/data/index.js +++ b/packages/kit/src/runtime/server/data/index.js @@ -1,5 +1,5 @@ import { text } from '@sveltejs/kit'; -import { HttpError, SvelteKitError, Redirect, copy_event_state } from '@sveltejs/kit/internal'; +import { HttpError, SvelteKitError, Redirect } from '@sveltejs/kit/internal'; import { normalize_error } from '../../../utils/error.js'; import { once } from '../../../utils/functions.js'; import { load_server_data } from '../page/load_data.js'; @@ -11,6 +11,7 @@ import { text_encoder } from '../../utils.js'; /** * @param {import('@sveltejs/kit').RequestEvent} event + * @param {import('types').RequestState} event_state * @param {import('types').SSRRoute} route * @param {import('types').SSROptions} options * @param {import('@sveltejs/kit').SSRManifest} manifest @@ -21,6 +22,7 @@ import { text_encoder } from '../../utils.js'; */ export async function render_data( event, + event_state, route, options, manifest, @@ -44,7 +46,7 @@ export async function render_data( const url = new URL(event.url); url.pathname = normalize_path(url.pathname, trailing_slash); - const new_event = copy_event_state(event, { ...event, url }); + const new_event = { ...event, url }; const functions = node_ids.map((n, i) => { return once(async () => { @@ -60,6 +62,7 @@ export async function render_data( // load this. for the child, return as is. for the final result, stream things return load_server_data({ event: new_event, + event_state, state, node, parent: async () => { @@ -107,7 +110,7 @@ export async function render_data( return /** @type {import('types').ServerErrorNode} */ ({ type: 'error', - error: await handle_error_and_jsonify(event, options, error), + error: await handle_error_and_jsonify(event, event_state, options, error), status: error instanceof HttpError || error instanceof SvelteKitError ? error.status @@ -117,7 +120,7 @@ export async function render_data( ) ); - const { data, chunks } = get_data_json(event, options, nodes); + const { data, chunks } = get_data_json(event, event_state, options, nodes); if (!chunks) { // use a normal JSON response where possible, so we get `content-length` @@ -152,7 +155,7 @@ export async function render_data( if (error instanceof Redirect) { return redirect_json_response(error); } else { - return json_response(await handle_error_and_jsonify(event, options, error), 500); + return json_response(await handle_error_and_jsonify(event, event_state, options, error), 500); } } } @@ -187,11 +190,12 @@ export function redirect_json_response(redirect) { * If the serialized data contains promises, `chunks` will be an * async iterable containing their resolutions * @param {import('@sveltejs/kit').RequestEvent} event + * @param {import('types').RequestState} event_state * @param {import('types').SSROptions} options * @param {Array} nodes * @returns {{ data: string, chunks: AsyncIterable | null }} */ -export function get_data_json(event, options, nodes) { +export function get_data_json(event, event_state, options, nodes) { let promise_id = 1; let count = 0; @@ -214,7 +218,7 @@ export function get_data_json(event, options, nodes) { .catch( /** @param {any} e */ async (e) => { key = 'error'; - return handle_error_and_jsonify(event, options, /** @type {any} */ (e)); + return handle_error_and_jsonify(event, event_state, options, /** @type {any} */ (e)); } ) .then( @@ -226,6 +230,7 @@ export function get_data_json(event, options, nodes) { } catch { const error = await handle_error_and_jsonify( event, + event_state, options, new Error(`Failed to serialize promise while rendering ${event.route.id}`) ); diff --git a/packages/kit/src/runtime/server/endpoint.js b/packages/kit/src/runtime/server/endpoint.js index eca20aabcaa0..124ab9edf0b4 100644 --- a/packages/kit/src/runtime/server/endpoint.js +++ b/packages/kit/src/runtime/server/endpoint.js @@ -1,15 +1,16 @@ -import { Redirect, with_event } from '@sveltejs/kit/internal'; +import { Redirect, with_request_store } from '@sveltejs/kit/internal'; import { ENDPOINT_METHODS, PAGE_METHODS } from '../../constants.js'; import { negotiate } from '../../utils/http.js'; import { method_not_allowed } from './utils.js'; /** * @param {import('@sveltejs/kit').RequestEvent} event + * @param {import('types').RequestState} event_state * @param {import('types').SSREndpoint} mod * @param {import('types').SSRState} state * @returns {Promise} */ -export async function render_endpoint(event, mod, state) { +export async function render_endpoint(event, event_state, mod, state) { const method = /** @type {import('types').HttpMethod} */ (event.request.method); let handler = mod[method] || mod.fallback; @@ -40,7 +41,7 @@ export async function render_endpoint(event, mod, state) { } try { - const response = await with_event(event, () => + const response = await with_request_store({ event, state: event_state }, () => handler(/** @type {import('@sveltejs/kit').RequestEvent>} */ (event)) ); diff --git a/packages/kit/src/runtime/server/page/actions.js b/packages/kit/src/runtime/server/page/actions.js index 83d089d326d8..cac5f1b0d009 100644 --- a/packages/kit/src/runtime/server/page/actions.js +++ b/packages/kit/src/runtime/server/page/actions.js @@ -8,7 +8,7 @@ import { Redirect, ActionFailure, SvelteKitError, - with_event, + with_request_store, merge_tracing } from '@sveltejs/kit/internal'; import { get_status, normalize_error } from '../../../utils/error.js'; @@ -28,10 +28,11 @@ export function is_action_json_request(event) { /** * @param {RequestEvent} event + * @param {import('types').RequestState} event_state * @param {SSROptions} options * @param {SSRNode['server'] | undefined} server */ -export async function handle_action_json_request(event, options, server) { +export async function handle_action_json_request(event, event_state, options, server) { const actions = server?.actions; if (!actions) { @@ -44,7 +45,7 @@ export async function handle_action_json_request(event, options, server) { return action_json( { type: 'error', - error: await handle_error_and_jsonify(event, options, no_actions_error) + error: await handle_error_and_jsonify(event, event_state, options, no_actions_error) }, { status: no_actions_error.status, @@ -60,7 +61,7 @@ export async function handle_action_json_request(event, options, server) { check_named_default_separate(actions); try { - const data = await call_action(event, actions); + const data = await call_action(event, event_state, actions); if (__SVELTEKIT_DEV__) { validate_action_return(data); @@ -101,7 +102,12 @@ export async function handle_action_json_request(event, options, server) { return action_json( { type: 'error', - error: await handle_error_and_jsonify(event, options, check_incorrect_fail_use(err)) + error: await handle_error_and_jsonify( + event, + event_state, + options, + check_incorrect_fail_use(err) + ) }, { status: get_status(err) @@ -147,10 +153,11 @@ export function is_action_request(event) { /** * @param {RequestEvent} event + * @param {import('types').RequestState} event_state * @param {SSRNode['server'] | undefined} server * @returns {Promise} */ -export async function handle_action_request(event, server) { +export async function handle_action_request(event, event_state, server) { const actions = server?.actions; if (!actions) { @@ -173,7 +180,7 @@ export async function handle_action_request(event, server) { check_named_default_separate(actions); try { - const data = await call_action(event, actions); + const data = await call_action(event, event_state, actions); if (__SVELTEKIT_DEV__) { validate_action_return(data); @@ -224,10 +231,11 @@ function check_named_default_separate(actions) { /** * @param {RequestEvent} event + * @param {import('types').RequestState} event_state * @param {NonNullable} actions * @throws {Redirect | HttpError | SvelteKitError | Error} */ -async function call_action(event, actions) { +async function call_action(event, event_state, actions) { const url = new URL(event.request.url); let name = 'default'; @@ -263,7 +271,10 @@ async function call_action(event, actions) { 'http.route': event.route.id || 'unknown' }, fn: async (current) => { - const result = await with_event(merge_tracing(event, current), () => action(event)); + const traced_event = merge_tracing(event, current); + const result = await with_request_store({ event: traced_event, state: event_state }, () => + action(traced_event) + ); if (result instanceof ActionFailure) { current.setAttributes({ 'sveltekit.form_action.result.type': 'failure', diff --git a/packages/kit/src/runtime/server/page/index.js b/packages/kit/src/runtime/server/page/index.js index 30e8115f612a..7d24641f062d 100644 --- a/packages/kit/src/runtime/server/page/index.js +++ b/packages/kit/src/runtime/server/page/index.js @@ -25,6 +25,7 @@ const MAX_DEPTH = 10; /** * @param {import('@sveltejs/kit').RequestEvent} event + * @param {import('types').RequestState} event_state * @param {import('types').PageNodeIndexes} page * @param {import('types').SSROptions} options * @param {import('@sveltejs/kit').SSRManifest} manifest @@ -33,7 +34,16 @@ const MAX_DEPTH = 10; * @param {import('types').RequiredResolveOptions} resolve_opts * @returns {Promise} */ -export async function render_page(event, page, options, manifest, state, nodes, resolve_opts) { +export async function render_page( + event, + event_state, + page, + options, + manifest, + state, + nodes, + resolve_opts +) { if (state.depth > MAX_DEPTH) { // infinite request cycle detected return text(`Not found: ${event.url.pathname}`, { @@ -43,7 +53,7 @@ export async function render_page(event, page, options, manifest, state, nodes, if (is_action_json_request(event)) { const node = await manifest._.nodes[page.leaf](); - return handle_action_json_request(event, options, node?.server); + return handle_action_json_request(event, event_state, options, node?.server); } try { @@ -57,11 +67,11 @@ export async function render_page(event, page, options, manifest, state, nodes, if (is_action_request(event)) { const remote_id = get_remote_action(event.url); if (remote_id) { - action_result = await handle_remote_form_post(event, manifest, remote_id); + action_result = await handle_remote_form_post(event, event_state, manifest, remote_id); } else { // for action requests, first call handler in +page.server.js // (this also determines status code) - action_result = await handle_action_request(event, leaf_node.server); + action_result = await handle_action_request(event, event_state, leaf_node.server); } if (action_result?.type === 'redirect') { @@ -133,6 +143,7 @@ export async function render_page(event, page, options, manifest, state, nodes, status, error: null, event, + event_state, options, manifest, state, @@ -163,6 +174,7 @@ export async function render_page(event, page, options, manifest, state, nodes, return await load_server_data({ event, + event_state, state, node, parent: async () => { @@ -189,6 +201,7 @@ export async function render_page(event, page, options, manifest, state, nodes, try { return await load_data({ event, + event_state, fetched, node, parent: async () => { @@ -243,7 +256,7 @@ export async function render_page(event, page, options, manifest, state, nodes, } const status = get_status(err); - const error = await handle_error_and_jsonify(event, options, err); + const error = await handle_error_and_jsonify(event, event_state, options, err); while (i--) { if (page.errors[i]) { @@ -258,6 +271,7 @@ export async function render_page(event, page, options, manifest, state, nodes, return await render_response({ event, + event_state, options, manifest, state, @@ -293,6 +307,7 @@ export async function render_page(event, page, options, manifest, state, nodes, // ndjson format let { data, chunks } = get_data_json( event, + event_state, options, branch.map((node) => node?.server_data) ); @@ -311,6 +326,7 @@ export async function render_page(event, page, options, manifest, state, nodes, return await render_response({ event, + event_state, options, manifest, state, @@ -330,6 +346,7 @@ export async function render_page(event, page, options, manifest, state, nodes, // but the page failed to render, or that a prerendering error occurred return await respond_with_error({ event, + event_state, options, manifest, state, diff --git a/packages/kit/src/runtime/server/page/load_data.js b/packages/kit/src/runtime/server/page/load_data.js index 4451247b2cf5..bc98735549bc 100644 --- a/packages/kit/src/runtime/server/page/load_data.js +++ b/packages/kit/src/runtime/server/page/load_data.js @@ -1,7 +1,7 @@ import { DEV } from 'esm-env'; import { disable_search, make_trackable } from '../../../utils/url.js'; import { validate_depends, validate_load_response } from '../../shared.js'; -import { with_event, merge_tracing } from '@sveltejs/kit/internal'; +import { with_request_store, merge_tracing } from '@sveltejs/kit/internal'; import { record_span } from '../../telemetry/record_span.js'; import { get_node_type } from '../utils.js'; import { base64_encode, text_decoder } from '../../utils.js'; @@ -10,13 +10,14 @@ import { base64_encode, text_decoder } from '../../utils.js'; * Calls the user's server `load` function. * @param {{ * event: import('@sveltejs/kit').RequestEvent; + * event_state: import('types').RequestState; * state: import('types').SSRState; * node: import('types').SSRNode | undefined; * parent: () => Promise>; * }} opts * @returns {Promise} */ -export async function load_server_data({ event, state, node, parent }) { +export async function load_server_data({ event, event_state, state, node, parent }) { if (!node?.server) return null; let is_tracking = true; @@ -80,7 +81,7 @@ export async function load_server_data({ event, state, node, parent }) { }, fn: async (current) => { const traced_event = merge_tracing(event, current); - const result = await with_event(traced_event, () => + const result = await with_request_store({ event: traced_event, state: event_state }, () => load.call(null, { ...traced_event, fetch: (info, init) => { @@ -191,6 +192,7 @@ export async function load_server_data({ event, state, node, parent }) { * Calls the user's `load` function. * @param {{ * event: import('@sveltejs/kit').RequestEvent; + * event_state: import('types').RequestState; * fetched: import('./types.js').Fetched[]; * node: import('types').SSRNode | undefined; * parent: () => Promise>; @@ -203,6 +205,7 @@ export async function load_server_data({ event, state, node, parent }) { */ export async function load_data({ event, + event_state, fetched, node, parent, @@ -229,7 +232,7 @@ export async function load_data({ }, fn: async (current) => { const traced_event = merge_tracing(event, current); - return with_event(traced_event, () => + return with_request_store({ event: traced_event, state: event_state }, () => load.call(null, { url: event.url, params: event.params, diff --git a/packages/kit/src/runtime/server/page/render.js b/packages/kit/src/runtime/server/page/render.js index 35c4442e6d55..1fb5f250b323 100644 --- a/packages/kit/src/runtime/server/page/render.js +++ b/packages/kit/src/runtime/server/page/render.js @@ -15,7 +15,7 @@ import { SVELTE_KIT_ASSETS } from '../../../constants.js'; import { SCHEME } from '../../../utils/url.js'; import { create_server_routing_response, generate_route_object } from './server_routing.js'; import { add_resolution_suffix } from '../../pathname.js'; -import { with_event, get_event_state } from '@sveltejs/kit/internal'; +import { with_request_store } from '@sveltejs/kit/internal'; import { text_encoder } from '../../utils.js'; // TODO rename this function/module @@ -37,6 +37,7 @@ const updated = { * status: number; * error: App.Error | null; * event: import('@sveltejs/kit').RequestEvent; + * event_state: import('types').RequestState; * resolve_opts: import('types').RequiredResolveOptions; * action_result?: import('@sveltejs/kit').ActionResult; * }} opts @@ -51,6 +52,7 @@ export async function render_response({ status, error = null, event, + event_state, resolve_opts, action_result }) { @@ -189,14 +191,18 @@ export async function render_response({ }; try { - rendered = with_event(event, () => options.root.render(props, render_opts)); + rendered = with_request_store({ event, state: event_state }, () => + options.root.render(props, render_opts) + ); } finally { globalThis.fetch = fetch; paths.reset(); } } else { try { - rendered = with_event(event, () => options.root.render(props, render_opts)); + rendered = with_request_store({ event, state: event_state }, () => + options.root.render(props, render_opts) + ); } finally { paths.reset(); } @@ -287,6 +293,7 @@ export async function render_response({ const { data, chunks } = get_data( event, + event_state, options, branch.map((b) => b.server_data), csp, @@ -376,7 +383,7 @@ export async function render_response({ }`); } - const { remote_data } = get_event_state(event); + const { remote_data } = event_state; if (remote_data) { /** @type {Record} */ @@ -603,13 +610,14 @@ export async function render_response({ * If the serialized data contains promises, `chunks` will be an * async iterable containing their resolutions * @param {import('@sveltejs/kit').RequestEvent} event + * @param {import('types').RequestState} event_state * @param {import('types').SSROptions} options * @param {Array} nodes * @param {import('./csp.js').Csp} csp * @param {string} global * @returns {{ data: string, chunks: AsyncIterable | null }} */ -function get_data(event, options, nodes, csp, global) { +function get_data(event, event_state, options, nodes, csp, global) { let promise_id = 1; let count = 0; @@ -625,7 +633,7 @@ function get_data(event, options, nodes, csp, global) { .then(/** @param {any} data */ (data) => ({ data })) .catch( /** @param {any} error */ async (error) => ({ - error: await handle_error_and_jsonify(event, options, error) + error: await handle_error_and_jsonify(event, event_state, options, error) }) ) .then( @@ -641,6 +649,7 @@ function get_data(event, options, nodes, csp, global) { } catch { error = await handle_error_and_jsonify( event, + event_state, options, new Error(`Failed to serialize promise while rendering ${event.route.id}`) ); diff --git a/packages/kit/src/runtime/server/page/respond_with_error.js b/packages/kit/src/runtime/server/page/respond_with_error.js index bb3e99054507..b1a6ae9ae606 100644 --- a/packages/kit/src/runtime/server/page/respond_with_error.js +++ b/packages/kit/src/runtime/server/page/respond_with_error.js @@ -12,6 +12,7 @@ import { PageNodes } from '../../../utils/page_nodes.js'; /** * @param {{ * event: import('@sveltejs/kit').RequestEvent; + * event_state: import('types').RequestState; * options: import('types').SSROptions; * manifest: import('@sveltejs/kit').SSRManifest; * state: import('types').SSRState; @@ -22,6 +23,7 @@ import { PageNodes } from '../../../utils/page_nodes.js'; */ export async function respond_with_error({ event, + event_state, options, manifest, state, @@ -49,6 +51,7 @@ export async function respond_with_error({ const server_data_promise = load_server_data({ event, + event_state, state, node: default_layout, // eslint-disable-next-line @typescript-eslint/require-await @@ -59,6 +62,7 @@ export async function respond_with_error({ const data = await load_data({ event, + event_state, fetched, node: default_layout, // eslint-disable-next-line @typescript-eslint/require-await @@ -92,10 +96,11 @@ export async function respond_with_error({ csr }, status, - error: await handle_error_and_jsonify(event, options, error), + error: await handle_error_and_jsonify(event, event_state, options, error), branch, fetched, event, + event_state, resolve_opts }); } catch (e) { @@ -108,7 +113,7 @@ export async function respond_with_error({ return static_error_page( options, get_status(e), - (await handle_error_and_jsonify(event, options, e)).message + (await handle_error_and_jsonify(event, event_state, options, e)).message ); } } diff --git a/packages/kit/src/runtime/server/remote.js b/packages/kit/src/runtime/server/remote.js index 31b9e42c804f..326dd257c7af 100644 --- a/packages/kit/src/runtime/server/remote.js +++ b/packages/kit/src/runtime/server/remote.js @@ -1,13 +1,12 @@ /** @import { ActionResult, RemoteForm, RequestEvent, SSRManifest } from '@sveltejs/kit' */ -/** @import { RemoteFunctionResponse, RemoteInfo, SSROptions } from 'types' */ +/** @import { RemoteFunctionResponse, RemoteInfo, RequestState, SSROptions } from 'types' */ import { json, error } from '@sveltejs/kit'; import { HttpError, Redirect, SvelteKitError, - with_event, - get_event_state, + with_request_store, merge_tracing } from '@sveltejs/kit/internal'; import { app_dir, base } from '__sveltekit/paths'; @@ -20,7 +19,7 @@ import { DEV } from 'esm-env'; import { record_span } from '../telemetry/record_span.js'; /** @type {typeof handle_remote_call_internal} */ -export async function handle_remote_call(event, options, manifest, id) { +export async function handle_remote_call(event, state, options, manifest, id) { return record_span({ name: 'sveltekit.remote.call', attributes: { @@ -28,8 +27,8 @@ export async function handle_remote_call(event, options, manifest, id) { }, fn: async (current) => { const traced_event = merge_tracing(event, current); - return with_event(traced_event, () => - handle_remote_call_internal(traced_event, options, manifest, id) + return with_request_store({ event: traced_event, state }, () => + handle_remote_call_internal(traced_event, state, options, manifest, id) ); } }); @@ -37,11 +36,12 @@ export async function handle_remote_call(event, options, manifest, id) { /** * @param {RequestEvent} event + * @param {RequestState} state * @param {SSROptions} options * @param {SSRManifest} manifest * @param {string} id */ -async function handle_remote_call_internal(event, options, manifest, id) { +async function handle_remote_call_internal(event, state, options, manifest, id) { const [hash, name, prerender_args] = id.split('/'); const remotes = manifest._.remotes; @@ -83,7 +83,7 @@ async function handle_remote_call_internal(event, options, manifest, id) { form_data.delete('sveltekit:remote_refreshes'); const fn = info.fn; - const data = await with_event(event, () => fn(form_data)); + const data = await with_request_store({ event, state }, () => fn(form_data)); return json( /** @type {RemoteFunctionResponse} */ ({ @@ -98,7 +98,7 @@ async function handle_remote_call_internal(event, options, manifest, id) { /** @type {{ payload: string, refreshes: string[] }} */ const { payload, refreshes } = await event.request.json(); const arg = parse_remote_arg(payload, transport); - const data = await with_event(event, () => fn(arg)); + const data = await with_request_store({ event, state }, () => fn(arg)); return json( /** @type {RemoteFunctionResponse} */ ({ @@ -117,7 +117,9 @@ async function handle_remote_call_internal(event, options, manifest, id) { new URL(event.request.url).searchParams.get('payload') ); - const data = await with_event(event, () => fn(parse_remote_arg(payload, transport))); + const data = await with_request_store({ event, state }, () => + fn(parse_remote_arg(payload, transport)) + ); return json( /** @type {RemoteFunctionResponse} */ ({ @@ -137,7 +139,7 @@ async function handle_remote_call_internal(event, options, manifest, id) { return json( /** @type {RemoteFunctionResponse} */ ({ type: 'error', - error: await handle_error_and_jsonify(event, options, error), + error: await handle_error_and_jsonify(event, state, options, error), status: error instanceof HttpError || error instanceof SvelteKitError ? error.status : 500 }), { @@ -153,7 +155,7 @@ async function handle_remote_call_internal(event, options, manifest, id) { */ async function serialize_refreshes(client_refreshes) { const refreshes = { - ...get_event_state(event).refreshes, + ...state.refreshes, ...Object.fromEntries( await Promise.all( client_refreshes.map(async (key) => { @@ -168,7 +170,12 @@ async function handle_remote_call_internal(event, options, manifest, id) { if (!fn) error(400, 'Bad Request'); - return [key, await with_event(event, () => fn(parse_remote_arg(payload, transport)))]; + return [ + key, + await with_request_store({ event, state }, () => + fn(parse_remote_arg(payload, transport)) + ) + ]; }) ) ) @@ -179,7 +186,7 @@ async function handle_remote_call_internal(event, options, manifest, id) { } /** @type {typeof handle_remote_form_post_internal} */ -export async function handle_remote_form_post(event, manifest, id) { +export async function handle_remote_form_post(event, state, manifest, id) { return record_span({ name: 'sveltekit.remote.form.post', attributes: { @@ -187,8 +194,8 @@ export async function handle_remote_form_post(event, manifest, id) { }, fn: async (current) => { const traced_event = merge_tracing(event, current); - return with_event(traced_event, () => - handle_remote_form_post_internal(traced_event, manifest, id) + return with_request_store({ event: traced_event, state }, () => + handle_remote_form_post_internal(traced_event, state, manifest, id) ); } }); @@ -196,11 +203,12 @@ export async function handle_remote_form_post(event, manifest, id) { /** * @param {RequestEvent} event + * @param {RequestState} state * @param {SSRManifest} manifest * @param {string} id * @returns {Promise} */ -async function handle_remote_form_post_internal(event, manifest, id) { +async function handle_remote_form_post_internal(event, state, manifest, id) { const [hash, name, action_id] = id.split('/'); const remotes = manifest._.remotes; const module = await remotes[hash]?.(); @@ -225,14 +233,14 @@ async function handle_remote_form_post_internal(event, manifest, id) { if (action_id) { // @ts-expect-error - form = with_event(event, () => form.for(JSON.parse(action_id))); + form = with_request_store({ event, state }, () => form.for(JSON.parse(action_id))); } try { const form_data = await event.request.formData(); const fn = /** @type {RemoteInfo & { type: 'form' }} */ (/** @type {any} */ (form).__).fn; - await with_event(event, () => fn(form_data)); + await with_request_store({ event, state }, () => fn(form_data)); // We don't want the data to appear on `let { form } = $props()`, which is why we're not returning it. // It is instead available on `myForm.result`, setting of which happens within the remote `form` function. diff --git a/packages/kit/src/runtime/server/respond.js b/packages/kit/src/runtime/server/respond.js index 20326651d509..2e9293dc14ce 100644 --- a/packages/kit/src/runtime/server/respond.js +++ b/packages/kit/src/runtime/server/respond.js @@ -1,12 +1,11 @@ +/** @import { RequestState } from 'types' */ import { DEV } from 'esm-env'; import { json, text } from '@sveltejs/kit'; import { Redirect, SvelteKitError, - with_event, - add_event_state, merge_tracing, - copy_event_state + with_request_store } from '@sveltejs/kit/internal'; import { base, app_dir } from '__sveltekit/paths'; import { is_endpoint_request, render_endpoint } from './endpoint.js'; @@ -143,57 +142,62 @@ export async function internal_respond(request, options, manifest, state) { url ); + /** @type {RequestState} */ + const event_state = { + prerendering: state.prerendering, + transport: options.hooks.transport, + handleValidationError: options.hooks.handleValidationError, + tracing: { + record_span + } + }; + /** @type {import('@sveltejs/kit').RequestEvent} */ - const event = add_event_state({ - state, - options, - record_span, - event: { - cookies, - // @ts-expect-error `fetch` needs to be created after the `event` itself - fetch: null, - getClientAddress: - state.getClientAddress || - (() => { - throw new Error( - `${__SVELTEKIT_ADAPTER_NAME__} does not specify getClientAddress. Please raise an issue` - ); - }), - locals: {}, - params: {}, - platform: state.platform, - request, - route: { id: null }, - setHeaders: (new_headers) => { - if (__SVELTEKIT_DEV__) { - validateHeaders(new_headers); - } + const event = { + cookies, + // @ts-expect-error `fetch` needs to be created after the `event` itself + fetch: null, + getClientAddress: + state.getClientAddress || + (() => { + throw new Error( + `${__SVELTEKIT_ADAPTER_NAME__} does not specify getClientAddress. Please raise an issue` + ); + }), + locals: {}, + params: {}, + platform: state.platform, + request, + route: { id: null }, + setHeaders: (new_headers) => { + if (__SVELTEKIT_DEV__) { + validateHeaders(new_headers); + } - for (const key in new_headers) { - const lower = key.toLowerCase(); - const value = new_headers[key]; + for (const key in new_headers) { + const lower = key.toLowerCase(); + const value = new_headers[key]; - if (lower === 'set-cookie') { - throw new Error( - 'Use `event.cookies.set(name, value, options)` instead of `event.setHeaders` to set cookies' - ); - } else if (lower in headers) { - throw new Error(`"${key}" header is already set`); - } else { - headers[lower] = value; + if (lower === 'set-cookie') { + throw new Error( + 'Use `event.cookies.set(name, value, options)` instead of `event.setHeaders` to set cookies' + ); + } else if (lower in headers) { + throw new Error(`"${key}" header is already set`); + } else { + headers[lower] = value; - if (state.prerendering && lower === 'cache-control') { - state.prerendering.cache = /** @type {string} */ (value); - } + if (state.prerendering && lower === 'cache-control') { + state.prerendering.cache = /** @type {string} */ (value); } } - }, - url, - isDataRequest: is_data_request, - isSubRequest: state.depth > 0, - isRemoteRequest: !!remote_id - } - }); + } + }, + url, + isDataRequest: is_data_request, + isSubRequest: state.depth > 0, + isRemoteRequest: !!remote_id + }; event.fetch = create_fetch({ event, @@ -402,15 +406,15 @@ export async function internal_respond(request, options, manifest, state) { 'sveltekit.is_sub_request': event.isSubRequest }, fn: async (root_span) => { - const traced_event = copy_event_state(event, { + const traced_event = { ...event, tracing: { enabled: __SVELTEKIT_SERVER_TRACING_ENABLED__, root: root_span, current: root_span } - }); - return await with_event(traced_event, () => + }; + return await with_request_store({ event: traced_event, state: event_state }, () => options.hooks.handle({ event: traced_event, resolve: (event, opts) => { @@ -422,7 +426,7 @@ export async function internal_respond(request, options, manifest, state) { fn: async (resolve_span) => { // counter-intuitively, we need to clear the event, so that it's not // e.g. accessible when loading modules needed to handle the request - return with_event(null, () => + return with_request_store(null, () => resolve(merge_tracing(event, resolve_span), page_nodes, opts).then( (response) => { // add headers/cookies here, rather than inside `resolve`, so that we @@ -510,7 +514,7 @@ export async function internal_respond(request, options, manifest, state) { add_cookies_to_headers(response.headers, Object.values(new_cookies)); return response; } - return await handle_fatal_error(event, options, e); + return await handle_fatal_error(event, event_state, options, e); } /** @@ -531,6 +535,7 @@ export async function internal_respond(request, options, manifest, state) { if (options.hash_routing || state.prerendering?.fallback) { return await render_response({ event, + event_state, options, manifest, state, @@ -544,7 +549,7 @@ export async function internal_respond(request, options, manifest, state) { } if (remote_id) { - return await handle_remote_call(event, options, manifest, remote_id); + return await handle_remote_call(event, event_state, options, manifest, remote_id); } if (route) { @@ -556,6 +561,7 @@ export async function internal_respond(request, options, manifest, state) { if (is_data_request) { response = await render_data( event, + event_state, route, options, manifest, @@ -564,13 +570,14 @@ export async function internal_respond(request, options, manifest, state) { trailing_slash ); } else if (route.endpoint && (!route.page || is_endpoint_request(event))) { - response = await render_endpoint(event, await route.endpoint(), state); + response = await render_endpoint(event, event_state, await route.endpoint(), state); } else if (route.page) { if (!page_nodes) { throw new Error('page_nodes not found. This should never happen'); } else if (page_methods.has(method)) { response = await render_page( event, + event_state, route.page, options, manifest, @@ -663,6 +670,7 @@ export async function internal_respond(request, options, manifest, state) { return await respond_with_error({ event, + event_state, options, manifest, state, @@ -684,7 +692,7 @@ export async function internal_respond(request, options, manifest, state) { // and I don't even know how to describe it. need to investigate at some point // HttpError from endpoint can end up here - TODO should it be handled there instead? - return await handle_fatal_error(event, options, e); + return await handle_fatal_error(event, event_state, options, e); } finally { event.cookies.set = () => { throw new Error('Cannot use `cookies.set(...)` after the response has been generated'); diff --git a/packages/kit/src/runtime/server/utils.js b/packages/kit/src/runtime/server/utils.js index c9a05bcb2de8..4c2d2434c461 100644 --- a/packages/kit/src/runtime/server/utils.js +++ b/packages/kit/src/runtime/server/utils.js @@ -1,12 +1,11 @@ import { DEV } from 'esm-env'; import { json, text } from '@sveltejs/kit'; -import { HttpError } from '@sveltejs/kit/internal'; +import { HttpError, with_request_store } from '@sveltejs/kit/internal'; import { coalesce_to_error, get_message, get_status } from '../../utils/error.js'; import { negotiate } from '../../utils/http.js'; import { fix_stack_trace } from '../shared-server.js'; import { ENDPOINT_METHODS } from '../../constants.js'; import { escape_html } from '../../utils/escape.js'; -import { with_event } from '../../exports/internal/event.js'; /** @param {any} body */ export function is_pojo(body) { @@ -67,13 +66,14 @@ export function static_error_page(options, status, message) { /** * @param {import('@sveltejs/kit').RequestEvent} event + * @param {import('types').RequestState} state * @param {import('types').SSROptions} options * @param {unknown} error */ -export async function handle_fatal_error(event, options, error) { +export async function handle_fatal_error(event, state, options, error) { error = error instanceof HttpError ? error : coalesce_to_error(error); const status = get_status(error); - const body = await handle_error_and_jsonify(event, options, error); + const body = await handle_error_and_jsonify(event, state, options, error); // ideally we'd use sec-fetch-dest instead, but Safari — quelle surprise — doesn't support it const type = negotiate(event.request.headers.get('accept') || 'text/html', [ @@ -92,11 +92,12 @@ export async function handle_fatal_error(event, options, error) { /** * @param {import('@sveltejs/kit').RequestEvent} event + * @param {import('types').RequestState} state * @param {import('types').SSROptions} options * @param {any} error * @returns {Promise} */ -export async function handle_error_and_jsonify(event, options, error) { +export async function handle_error_and_jsonify(event, state, options, error) { if (error instanceof HttpError) { return error.body; } @@ -109,7 +110,7 @@ export async function handle_error_and_jsonify(event, options, error) { const message = get_message(error); return ( - (await with_event(event, () => + (await with_request_store({ event, state }, () => options.hooks.handleError({ error, event, status, message }) )) ?? { message } ); diff --git a/packages/kit/src/types/internal.d.ts b/packages/kit/src/types/internal.d.ts index d31c67a281b7..72e18977ff32 100644 --- a/packages/kit/src/types/internal.d.ts +++ b/packages/kit/src/types/internal.d.ts @@ -573,5 +573,26 @@ export type RecordSpan = (options: { fn: (current: Span) => Promise; }) => Promise; +/** + * Internal state associated with the current `RequestEvent`, + * used for tracking things like remote function calls + */ +export interface RequestState { + prerendering: PrerenderOptions | undefined; + transport: ServerHooks['transport']; + handleValidationError: ServerHooks['handleValidationError']; + tracing: { + record_span: RecordSpan; + }; + form_instances?: Map; + remote_data?: Record>; + refreshes?: Record; +} + +export interface RequestStore { + event: RequestEvent; + state: RequestState; +} + export * from '../exports/index.js'; export * from './private.js'; diff --git a/packages/kit/test/apps/basics/src/hooks.server.js b/packages/kit/test/apps/basics/src/hooks.server.js index dfbf0ff3e3f5..e6ec0e695964 100644 --- a/packages/kit/test/apps/basics/src/hooks.server.js +++ b/packages/kit/test/apps/basics/src/hooks.server.js @@ -65,7 +65,8 @@ export const handleValidationError = ({ issues }) => { }; export const handle = sequence( - ({ event, resolve }) => { + // eslint-disable-next-line prefer-arrow-callback -- this needs a name for tests + function set_tracing_test_id({ event, resolve }) { const test_id = !building && event.url.searchParams.get('test_id'); if (test_id) { event.tracing.root.setAttribute('test_id', test_id); diff --git a/packages/kit/test/apps/basics/test/server.test.js b/packages/kit/test/apps/basics/test/server.test.js index a7401f0ea7b4..91798f8d3e28 100644 --- a/packages/kit/test/apps/basics/test/server.test.js +++ b/packages/kit/test/apps/basics/test/server.test.js @@ -820,10 +820,8 @@ test.describe('tracing', () => { span_id: expect.any(String), children: expect.arrayContaining([ expect.objectContaining({ - name: 'sveltekit.handle.child', - attributes: expect.objectContaining({ - 'sveltekit.handle.child.index': 0 - }) + name: 'sveltekit.handle.sequenced.set_tracing_test_id', + attributes: {} }) ]) }); @@ -912,10 +910,8 @@ test.describe('tracing', () => { span_id: expect.any(String), children: expect.arrayContaining([ expect.objectContaining({ - name: 'sveltekit.handle.child', - attributes: expect.objectContaining({ - 'sveltekit.handle.child.index': 0 - }) + name: 'sveltekit.handle.sequenced.set_tracing_test_id', + attributes: {} }) ]) }); @@ -984,10 +980,8 @@ test.describe('tracing', () => { span_id: expect.any(String), children: expect.arrayContaining([ expect.objectContaining({ - name: 'sveltekit.handle.child', - attributes: expect.objectContaining({ - 'sveltekit.handle.child.index': 0 - }) + name: 'sveltekit.handle.sequenced.set_tracing_test_id', + attributes: {} }) ]) }); @@ -1042,10 +1036,8 @@ test.describe('tracing', () => { span_id: expect.any(String), children: expect.arrayContaining([ expect.objectContaining({ - name: 'sveltekit.handle.child', - attributes: expect.objectContaining({ - 'sveltekit.handle.child.index': 0 - }) + name: 'sveltekit.handle.sequenced.set_tracing_test_id', + attributes: {} }) ]) }); @@ -1134,10 +1126,8 @@ test.describe('tracing', () => { span_id: expect.any(String), children: expect.arrayContaining([ expect.objectContaining({ - name: 'sveltekit.handle.child', - attributes: expect.objectContaining({ - 'sveltekit.handle.child.index': 0 - }) + name: 'sveltekit.handle.sequenced.set_tracing_test_id', + attributes: {} }) ]) }); @@ -1200,10 +1190,8 @@ test.describe('tracing', () => { span_id: expect.any(String), children: expect.arrayContaining([ expect.objectContaining({ - name: 'sveltekit.handle.child', - attributes: expect.objectContaining({ - 'sveltekit.handle.child.index': 0 - }) + name: 'sveltekit.handle.sequenced.set_tracing_test_id', + attributes: {} }) ]) }); From a1cad378ab18547f4a083c5c54cb9107f056d949 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 12 Aug 2025 20:02:59 -0400 Subject: [PATCH 52/74] Update documentation/docs/30-advanced/68-observability.md --- documentation/docs/30-advanced/68-observability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/30-advanced/68-observability.md b/documentation/docs/30-advanced/68-observability.md index 1d38b42de821..c42878b84697 100644 --- a/documentation/docs/30-advanced/68-observability.md +++ b/documentation/docs/30-advanced/68-observability.md @@ -19,7 +19,7 @@ Just telling SvelteKit to emit spans won't get you far, though -- you need to ac To enable both of these features, add the following to your `svelte.config.js`: -```diff +```js /// file: svelte.config.js export default { kit: { From 3322f8958d623ca6a33b8abb0439f442192a8fd1 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Tue, 12 Aug 2025 18:06:08 -0600 Subject: [PATCH 53/74] remove config --- packages/kit/src/core/config/index.js | 2 - packages/kit/src/core/config/index.spec.js | 3 - packages/kit/src/core/config/options.js | 3 - packages/kit/src/exports/public.d.ts | 7 - packages/kit/src/exports/vite/dev/index.js | 6 +- packages/kit/src/exports/vite/index.js | 3 +- packages/kit/types/index.d.ts | 173 ++++++++++++++++++++- 7 files changed, 170 insertions(+), 27 deletions(-) diff --git a/packages/kit/src/core/config/index.js b/packages/kit/src/core/config/index.js index af18dfee10bf..7fc38bc483dd 100644 --- a/packages/kit/src/core/config/index.js +++ b/packages/kit/src/core/config/index.js @@ -105,8 +105,6 @@ function process_config(config, { cwd = process.cwd() } = {}) { validated.kit.files.hooks.client = path.resolve(cwd, validated.kit.files.hooks.client); validated.kit.files.hooks.server = path.resolve(cwd, validated.kit.files.hooks.server); validated.kit.files.hooks.universal = path.resolve(cwd, validated.kit.files.hooks.universal); - } else if (key === 'tracing') { - validated.kit.files.tracing.server = path.resolve(cwd, validated.kit.files.tracing.server); } else { // @ts-expect-error validated.kit.files[key] = path.resolve(cwd, validated.kit.files[key]); diff --git a/packages/kit/src/core/config/index.spec.js b/packages/kit/src/core/config/index.spec.js index dfc045b0716d..ac7fafbfa52c 100644 --- a/packages/kit/src/core/config/index.spec.js +++ b/packages/kit/src/core/config/index.spec.js @@ -87,9 +87,6 @@ const get_defaults = (prefix = '') => ({ server: join(prefix, 'src/hooks.server'), universal: join(prefix, 'src/hooks') }, - tracing: { - server: join(prefix, 'src/tracing.server') - }, lib: join(prefix, 'src/lib'), params: join(prefix, 'src/params'), routes: join(prefix, 'src/routes'), diff --git a/packages/kit/src/core/config/options.js b/packages/kit/src/core/config/options.js index e26c57409560..1b4009c16b8c 100644 --- a/packages/kit/src/core/config/options.js +++ b/packages/kit/src/core/config/options.js @@ -135,9 +135,6 @@ const options = object( server: string(join('src', 'hooks.server')), universal: string(join('src', 'hooks')) }), - tracing: object({ - server: string(join('src', 'tracing.server')) - }), lib: string(join('src', 'lib')), params: string(join('src', 'params')), routes: string(join('src', 'routes')), diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 2fc5a36d6583..f2ee63ac82bb 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -513,13 +513,6 @@ export interface KitConfig { */ universal?: string; }; - /** - * the location of your server tracing file - * @default "src/tracing.server" - */ - tracing?: { - server?: string; - }; /** * your app's internal library, accessible throughout the codebase as `$lib` * @default "src/lib" diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 0cbbe50dfe92..23f986c8ebc2 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -376,7 +376,7 @@ export async function dev(vite, vite_config, svelte_config) { sync.update(svelte_config, manifest_data, file); }); - const { appTemplate, errorTemplate, serviceWorker, hooks, tracing } = svelte_config.kit.files; + const { appTemplate, errorTemplate, serviceWorker, hooks } = svelte_config.kit.files; // vite client only executes a full reload if the triggering html file path is index.html // kit defaults to src/app.html, so unless user changed that to index.html @@ -395,7 +395,7 @@ export async function dev(vite, vite_config, svelte_config) { file === errorTemplate || file.startsWith(serviceWorker) || file.startsWith(hooks.server) || - file.startsWith(tracing.server) + file.startsWith(path.resolve(cwd, 'src/tracing.server')) ) { sync.server(svelte_config); } @@ -502,7 +502,7 @@ export async function dev(vite, vite_config, svelte_config) { return; } - const resolved_tracing = resolve_entry(tracing.server); + const resolved_tracing = resolve_entry(path.resolve(cwd, 'src/tracing.server')); if (resolved_tracing) { await vite.ssrLoadModule(resolved_tracing); } diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index cb990eb5731f..b4cc82916297 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -784,7 +784,8 @@ async function kit({ svelte_config }) { }); // ...and the server tracing file - const server_tracing = resolve_entry(kit.files.tracing.server); + // TODO: Resolve this however we resolve all of the other files after we deprecate the `files` options + const server_tracing = resolve_entry(path.resolve(cwd, 'src/tracing.server')); if (server_tracing) { const { adapter } = kit; if (adapter && !adapter.supports?.tracing?.()) { diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index f7be510fc5bf..99971191de53 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -489,13 +489,6 @@ declare module '@sveltejs/kit' { */ universal?: string; }; - /** - * the location of your server tracing file - * @default "src/tracing.server" - */ - tracing?: { - server?: string; - }; /** * your app's internal library, accessible throughout the codebase as `$lib` * @default "src/lib" @@ -2733,8 +2726,10 @@ declare module '$app/paths' { declare module '$app/server' { // @ts-ignore import { LayoutParams as AppLayoutParams, RouteId as AppRouteId } from '$app/types' - import type { RequestEvent, RemoteCommand, RemoteForm, RemotePrerenderFunction, RemoteQueryFunction } from '@sveltejs/kit'; + import type { RemoteCommand, RemoteForm, RemotePrerenderFunction, RemoteQueryFunction } from '@sveltejs/kit'; import type { StandardSchemaV1 } from '@standard-schema/spec'; + import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams_1 } from '$app/types'; + import type { Span } from '@opentelemetry/api'; /** * Read the contents of an imported asset from the filesystem * @example @@ -2844,6 +2839,168 @@ declare module '$app/server' { * @since 2.27 */ export function query(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise): RemoteQueryFunction, Output>; + interface Cookies { + /** + * Gets a cookie that was previously set with `cookies.set`, or from the request headers. + * @param name the name of the cookie + * @param opts the options, passed directly to `cookie.parse`. See documentation [here](https://github.com/jshttp/cookie#cookieparsestr-options) + */ + get: (name: string, opts?: import('cookie').CookieParseOptions) => string | undefined; + + /** + * Gets all cookies that were previously set with `cookies.set`, or from the request headers. + * @param opts the options, passed directly to `cookie.parse`. See documentation [here](https://github.com/jshttp/cookie#cookieparsestr-options) + */ + getAll: (opts?: import('cookie').CookieParseOptions) => Array<{ name: string; value: string }>; + + /** + * Sets a cookie. This will add a `set-cookie` header to the response, but also make the cookie available via `cookies.get` or `cookies.getAll` during the current request. + * + * The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`. + * + * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children + * @param name the name of the cookie + * @param value the cookie value + * @param opts the options, passed directly to `cookie.serialize`. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) + */ + set: ( + name: string, + value: string, + opts: import('cookie').CookieSerializeOptions & { path: string } + ) => void; + + /** + * Deletes a cookie by setting its value to an empty string and setting the expiry date in the past. + * + * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children + * @param name the name of the cookie + * @param opts the options, passed directly to `cookie.serialize`. The `path` must match the path of the cookie you want to delete. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) + */ + delete: (name: string, opts: import('cookie').CookieSerializeOptions & { path: string }) => void; + + /** + * Serialize a cookie name-value pair into a `Set-Cookie` header string, but don't apply it to the response. + * + * The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`. + * + * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children + * + * @param name the name of the cookie + * @param value the cookie value + * @param opts the options, passed directly to `cookie.serialize`. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) + */ + serialize: ( + name: string, + value: string, + opts: import('cookie').CookieSerializeOptions & { path: string } + ) => string; + } + + interface RequestEvent< + Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + RouteId extends AppRouteId | null = AppRouteId | null + > { + /** + * Get or set cookies related to the current request + */ + cookies: Cookies; + /** + * `fetch` is equivalent to the [native `fetch` web API](https://developer.mozilla.org/en-US/docs/Web/API/fetch), with a few additional features: + * + * - It can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request. + * - It can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context). + * - Internal requests (e.g. for `+server.js` routes) go directly to the handler function when running on the server, without the overhead of an HTTP call. + * - During server-side rendering, the response will be captured and inlined into the rendered HTML by hooking into the `text` and `json` methods of the `Response` object. Note that headers will _not_ be serialized, unless explicitly included via [`filterSerializedResponseHeaders`](https://svelte.dev/docs/kit/hooks#Server-hooks-handle) + * - During hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request. + * + * You can learn more about making credentialed requests with cookies [here](https://svelte.dev/docs/kit/load#Cookies). + */ + fetch: typeof fetch; + /** + * The client's IP address, set by the adapter. + */ + getClientAddress: () => string; + /** + * Contains custom data that was added to the request within the [`server handle hook`](https://svelte.dev/docs/kit/hooks#Server-hooks-handle). + */ + locals: App.Locals; + /** + * The parameters of the current route - e.g. for a route like `/blog/[slug]`, a `{ slug: string }` object. + */ + params: Params; + /** + * Additional data made available through the adapter. + */ + platform: Readonly | undefined; + /** + * The original request object. + */ + request: Request; + /** + * Info about the current route. + */ + route: { + /** + * The ID of the current route - e.g. for `src/routes/blog/[slug]`, it would be `/blog/[slug]`. It is `null` when no route is matched. + */ + id: RouteId; + }; + /** + * If you need to set headers for the response, you can do so using the this method. This is useful if you want the page to be cached, for example: + * + * ```js + * /// file: src/routes/blog/+page.js + * export async function load({ fetch, setHeaders }) { + * const url = `https://cms.example.com/articles.json`; + * const response = await fetch(url); + * + * setHeaders({ + * age: response.headers.get('age'), + * 'cache-control': response.headers.get('cache-control') + * }); + * + * return response.json(); + * } + * ``` + * + * Setting the same header multiple times (even in separate `load` functions) is an error — you can only set a given header once. + * + * You cannot add a `set-cookie` header with `setHeaders` — use the [`cookies`](https://svelte.dev/docs/kit/@sveltejs-kit#Cookies) API instead. + */ + setHeaders: (headers: Record) => void; + /** + * The requested URL. + */ + url: URL; + /** + * `true` if the request comes from the client asking for `+page/layout.server.js` data. The `url` property will be stripped of the internal information + * related to the data request in this case. Use this property instead if the distinction is important to you. + */ + isDataRequest: boolean; + /** + * `true` for `+server.js` calls coming from SvelteKit without the overhead of actually making an HTTP request. This happens when you make same-origin `fetch` requests on the server. + */ + isSubRequest: boolean; + + /** + * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. + * @since 2.29.0 + */ + tracing: { + /** Whether tracing is enabled. */ + enabled: boolean; + /** The root span for the request. This span is named `sveltekit.handle.root`. */ + root: Span; + /** The span associated with the current `handle` hook, `load` function, or form action. */ + current: Span; + }; + + /** + * `true` if the request comes from the client via a remote function. The `url` property will be stripped of the internal information + * related to the data request in this case. Use this property instead if the distinction is important to you. + */ + isRemoteRequest: boolean; + } type RemotePrerenderInputsGenerator = () => MaybePromise; type MaybePromise = T | Promise; From 2fe0fbf3e75566f341d9f2bc33b564586b55caf8 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Tue, 12 Aug 2025 18:09:07 -0600 Subject: [PATCH 54/74] last feedbacks --- packages/kit/kit.vitest.config.js | 1 - pnpm-workspace.yaml | 1 - 2 files changed, 2 deletions(-) diff --git a/packages/kit/kit.vitest.config.js b/packages/kit/kit.vitest.config.js index 55e822235729..82502703e574 100644 --- a/packages/kit/kit.vitest.config.js +++ b/packages/kit/kit.vitest.config.js @@ -15,7 +15,6 @@ export default defineConfig({ alias: { '__sveltekit/paths': fileURLToPath(new URL('./test/mocks/path.js', import.meta.url)) }, - isolate: true, poolOptions: { threads: { singleThread: true diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c520b3835bcb..157ca9bb6b9e 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -15,6 +15,5 @@ catalog: '@playwright/test': '^1.51.1' '@sveltejs/vite-plugin-svelte': '^6.0.0-next.3' '@types/node': '^18.19.119' - 'cross-env': '^7.0.3' 'vitest': '^3.2.3' 'vite': '^6.3.5' From 98669e68f0fa7df26b46b409ffe8b6bcac44163b Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Tue, 12 Aug 2025 18:13:23 -0600 Subject: [PATCH 55/74] tests --- .../adapter-netlify/test/apps/basic/svelte.config.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/adapter-netlify/test/apps/basic/svelte.config.js b/packages/adapter-netlify/test/apps/basic/svelte.config.js index 9cbf9ba19a31..fe7386b1bf63 100644 --- a/packages/adapter-netlify/test/apps/basic/svelte.config.js +++ b/packages/adapter-netlify/test/apps/basic/svelte.config.js @@ -3,11 +3,11 @@ import adapter from '../../../index.js'; /** @type {import('@sveltejs/kit').Config} */ const config = { kit: { - adapter: adapter() - }, - experimental: { - tracing: { - serverFile: true + adapter: adapter(), + experimental: { + tracing: { + serverFile: true + } } } }; From 0c03fbed0d81bcb54d2039fe896aae2392475727 Mon Sep 17 00:00:00 2001 From: Chew Tee Ming Date: Wed, 13 Aug 2025 10:53:54 +0800 Subject: [PATCH 56/74] fix type generation and remove hack --- packages/kit/scripts/generate-dts.js | 8 +- packages/kit/src/exports/internal/event.js | 2 + packages/kit/src/exports/public.d.ts | 4 +- packages/kit/types/index.d.ts | 196 ++------------------- 4 files changed, 20 insertions(+), 190 deletions(-) diff --git a/packages/kit/scripts/generate-dts.js b/packages/kit/scripts/generate-dts.js index 1af5db6ae96b..e8579ec59054 100644 --- a/packages/kit/scripts/generate-dts.js +++ b/packages/kit/scripts/generate-dts.js @@ -1,5 +1,5 @@ import { createBundle } from 'dts-buddy'; -import { readFileSync, writeFileSync } from 'node:fs'; +import { readFileSync } from 'node:fs'; await createBundle({ output: 'types/index.d.ts', @@ -28,9 +28,3 @@ if (types.includes('__sveltekit/')) { types ); } - -// this is hacky as all hell but it gets the tests passing. might be a bug in dts-buddy? -// prettier-ignore -writeFileSync('./types/index.d.ts', types.replace("declare module '$app/server' {", `declare module '$app/server' { - // @ts-ignore - import { LayoutParams as AppLayoutParams, RouteId as AppRouteId } from '$app/types'`)); diff --git a/packages/kit/src/exports/internal/event.js b/packages/kit/src/exports/internal/event.js index f04ed91f13f2..80aaf7c7722e 100644 --- a/packages/kit/src/exports/internal/event.js +++ b/packages/kit/src/exports/internal/event.js @@ -1,4 +1,5 @@ /** @import { RequestStore } from 'types' */ +/** @import { RequestEvent } from '@sveltejs/kit' */ /** @type {RequestStore | null} */ let sync_store = null; @@ -19,6 +20,7 @@ import('node:async_hooks') * * In environments without [`AsyncLocalStorage`](https://nodejs.org/api/async_context.html#class-asynclocalstorage), this must be called synchronously (i.e. not after an `await`). * @since 2.20.0 + * @returns {RequestEvent} */ export function getRequestEvent() { const event = try_get_request_store()?.event; diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index f2ee63ac82bb..6c4c12eec6ee 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -17,8 +17,8 @@ import { RouteSegment } from '../types/private.js'; import { BuildData, SSRNodeLoader, SSRRoute, ValidatedConfig } from 'types'; -import type { SvelteConfig } from '@sveltejs/vite-plugin-svelte'; -import type { StandardSchemaV1 } from '@standard-schema/spec'; +import { SvelteConfig } from '@sveltejs/vite-plugin-svelte'; +import { StandardSchemaV1 } from '@standard-schema/spec'; import { RouteId as AppRouteId, LayoutParams as AppLayoutParams, diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 99971191de53..d18c7107368d 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -4,7 +4,7 @@ declare module '@sveltejs/kit' { import type { SvelteConfig } from '@sveltejs/vite-plugin-svelte'; import type { StandardSchemaV1 } from '@standard-schema/spec'; - import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams_1, ResolvedPathname } from '$app/types'; + import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams, ResolvedPathname } from '$app/types'; import type { Span } from '@opentelemetry/api'; /** * [Adapters](https://svelte.dev/docs/kit/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. @@ -919,7 +919,7 @@ declare module '@sveltejs/kit' { * rather than using `Load` directly. */ export type Load< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, InputData extends Record | null = Record | null, ParentData extends Record = Record, OutputData extends Record | void = Record | void, @@ -931,7 +931,7 @@ declare module '@sveltejs/kit' { * rather than using `LoadEvent` directly. */ export interface LoadEvent< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, Data extends Record | null = Record | null, ParentData extends Record = Record, RouteId extends AppRouteId | null = AppRouteId | null @@ -1052,7 +1052,7 @@ declare module '@sveltejs/kit' { } export interface NavigationEvent< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, RouteId extends AppRouteId | null = AppRouteId | null > { /** @@ -1078,7 +1078,7 @@ declare module '@sveltejs/kit' { * Information about the target of a specific navigation. */ export interface NavigationTarget< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, RouteId extends AppRouteId | null = AppRouteId | null > { /** @@ -1195,7 +1195,7 @@ declare module '@sveltejs/kit' { * The shape of the [`page`](https://svelte.dev/docs/kit/$app-state#page) reactive object and the [`$page`](https://svelte.dev/docs/kit/$app-stores) store. */ export interface Page< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, RouteId extends AppRouteId | null = AppRouteId | null > { /** @@ -1243,7 +1243,7 @@ declare module '@sveltejs/kit' { export type ParamMatcher = (param: string) => boolean; export interface RequestEvent< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, RouteId extends AppRouteId | null = AppRouteId | null > { /** @@ -1354,7 +1354,7 @@ declare module '@sveltejs/kit' { * It receives `Params` as the first generic argument, which you can skip by using [generated types](https://svelte.dev/docs/kit/types#Generated-types) instead. */ export type RequestHandler< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, RouteId extends AppRouteId | null = AppRouteId | null > = (event: RequestEvent) => MaybePromise; @@ -1435,14 +1435,14 @@ declare module '@sveltejs/kit' { * rather than using `ServerLoad` directly. */ export type ServerLoad< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, ParentData extends Record = Record, OutputData extends Record | void = Record | void, RouteId extends AppRouteId | null = AppRouteId | null > = (event: ServerLoadEvent) => MaybePromise; export interface ServerLoadEvent< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, ParentData extends Record = Record, RouteId extends AppRouteId | null = AppRouteId | null > extends RequestEvent { @@ -1524,7 +1524,7 @@ declare module '@sveltejs/kit' { * See [form actions](https://svelte.dev/docs/kit/form-actions) for more information. */ export type Action< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, OutputData extends Record | void = Record | void, RouteId extends AppRouteId | null = AppRouteId | null > = (event: RequestEvent) => MaybePromise; @@ -1534,7 +1534,7 @@ declare module '@sveltejs/kit' { * See [form actions](https://svelte.dev/docs/kit/form-actions) for more information. */ export type Actions< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, OutputData extends Record | void = Record | void, RouteId extends AppRouteId | null = AppRouteId | null > = Record>; @@ -2724,12 +2724,8 @@ declare module '$app/paths' { } declare module '$app/server' { - // @ts-ignore - import { LayoutParams as AppLayoutParams, RouteId as AppRouteId } from '$app/types' - import type { RemoteCommand, RemoteForm, RemotePrerenderFunction, RemoteQueryFunction } from '@sveltejs/kit'; + import type { RequestEvent, RemoteCommand, RemoteForm, RemotePrerenderFunction, RemoteQueryFunction } from '@sveltejs/kit'; import type { StandardSchemaV1 } from '@standard-schema/spec'; - import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams_1 } from '$app/types'; - import type { Span } from '@opentelemetry/api'; /** * Read the contents of an imported asset from the filesystem * @example @@ -2748,8 +2744,8 @@ declare module '$app/server' { * * In environments without [`AsyncLocalStorage`](https://nodejs.org/api/async_context.html#class-asynclocalstorage), this must be called synchronously (i.e. not after an `await`). * @since 2.20.0 - */ - export function getRequestEvent(): RequestEvent, any>; + * */ + export function getRequestEvent(): RequestEvent; /** * Creates a remote command. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2839,168 +2835,6 @@ declare module '$app/server' { * @since 2.27 */ export function query(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise): RemoteQueryFunction, Output>; - interface Cookies { - /** - * Gets a cookie that was previously set with `cookies.set`, or from the request headers. - * @param name the name of the cookie - * @param opts the options, passed directly to `cookie.parse`. See documentation [here](https://github.com/jshttp/cookie#cookieparsestr-options) - */ - get: (name: string, opts?: import('cookie').CookieParseOptions) => string | undefined; - - /** - * Gets all cookies that were previously set with `cookies.set`, or from the request headers. - * @param opts the options, passed directly to `cookie.parse`. See documentation [here](https://github.com/jshttp/cookie#cookieparsestr-options) - */ - getAll: (opts?: import('cookie').CookieParseOptions) => Array<{ name: string; value: string }>; - - /** - * Sets a cookie. This will add a `set-cookie` header to the response, but also make the cookie available via `cookies.get` or `cookies.getAll` during the current request. - * - * The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`. - * - * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children - * @param name the name of the cookie - * @param value the cookie value - * @param opts the options, passed directly to `cookie.serialize`. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) - */ - set: ( - name: string, - value: string, - opts: import('cookie').CookieSerializeOptions & { path: string } - ) => void; - - /** - * Deletes a cookie by setting its value to an empty string and setting the expiry date in the past. - * - * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children - * @param name the name of the cookie - * @param opts the options, passed directly to `cookie.serialize`. The `path` must match the path of the cookie you want to delete. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) - */ - delete: (name: string, opts: import('cookie').CookieSerializeOptions & { path: string }) => void; - - /** - * Serialize a cookie name-value pair into a `Set-Cookie` header string, but don't apply it to the response. - * - * The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`. - * - * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children - * - * @param name the name of the cookie - * @param value the cookie value - * @param opts the options, passed directly to `cookie.serialize`. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) - */ - serialize: ( - name: string, - value: string, - opts: import('cookie').CookieSerializeOptions & { path: string } - ) => string; - } - - interface RequestEvent< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, - RouteId extends AppRouteId | null = AppRouteId | null - > { - /** - * Get or set cookies related to the current request - */ - cookies: Cookies; - /** - * `fetch` is equivalent to the [native `fetch` web API](https://developer.mozilla.org/en-US/docs/Web/API/fetch), with a few additional features: - * - * - It can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request. - * - It can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context). - * - Internal requests (e.g. for `+server.js` routes) go directly to the handler function when running on the server, without the overhead of an HTTP call. - * - During server-side rendering, the response will be captured and inlined into the rendered HTML by hooking into the `text` and `json` methods of the `Response` object. Note that headers will _not_ be serialized, unless explicitly included via [`filterSerializedResponseHeaders`](https://svelte.dev/docs/kit/hooks#Server-hooks-handle) - * - During hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request. - * - * You can learn more about making credentialed requests with cookies [here](https://svelte.dev/docs/kit/load#Cookies). - */ - fetch: typeof fetch; - /** - * The client's IP address, set by the adapter. - */ - getClientAddress: () => string; - /** - * Contains custom data that was added to the request within the [`server handle hook`](https://svelte.dev/docs/kit/hooks#Server-hooks-handle). - */ - locals: App.Locals; - /** - * The parameters of the current route - e.g. for a route like `/blog/[slug]`, a `{ slug: string }` object. - */ - params: Params; - /** - * Additional data made available through the adapter. - */ - platform: Readonly | undefined; - /** - * The original request object. - */ - request: Request; - /** - * Info about the current route. - */ - route: { - /** - * The ID of the current route - e.g. for `src/routes/blog/[slug]`, it would be `/blog/[slug]`. It is `null` when no route is matched. - */ - id: RouteId; - }; - /** - * If you need to set headers for the response, you can do so using the this method. This is useful if you want the page to be cached, for example: - * - * ```js - * /// file: src/routes/blog/+page.js - * export async function load({ fetch, setHeaders }) { - * const url = `https://cms.example.com/articles.json`; - * const response = await fetch(url); - * - * setHeaders({ - * age: response.headers.get('age'), - * 'cache-control': response.headers.get('cache-control') - * }); - * - * return response.json(); - * } - * ``` - * - * Setting the same header multiple times (even in separate `load` functions) is an error — you can only set a given header once. - * - * You cannot add a `set-cookie` header with `setHeaders` — use the [`cookies`](https://svelte.dev/docs/kit/@sveltejs-kit#Cookies) API instead. - */ - setHeaders: (headers: Record) => void; - /** - * The requested URL. - */ - url: URL; - /** - * `true` if the request comes from the client asking for `+page/layout.server.js` data. The `url` property will be stripped of the internal information - * related to the data request in this case. Use this property instead if the distinction is important to you. - */ - isDataRequest: boolean; - /** - * `true` for `+server.js` calls coming from SvelteKit without the overhead of actually making an HTTP request. This happens when you make same-origin `fetch` requests on the server. - */ - isSubRequest: boolean; - - /** - * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.29.0 - */ - tracing: { - /** Whether tracing is enabled. */ - enabled: boolean; - /** The root span for the request. This span is named `sveltekit.handle.root`. */ - root: Span; - /** The span associated with the current `handle` hook, `load` function, or form action. */ - current: Span; - }; - - /** - * `true` if the request comes from the client via a remote function. The `url` property will be stripped of the internal information - * related to the data request in this case. Use this property instead if the distinction is important to you. - */ - isRemoteRequest: boolean; - } type RemotePrerenderInputsGenerator = () => MaybePromise; type MaybePromise = T | Promise; From 54831e7cae20433074241df63a36538aaf242d47 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 13 Aug 2025 07:41:53 -0400 Subject: [PATCH 57/74] em dashes and tabs --- .../docs/30-advanced/68-observability.md | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/documentation/docs/30-advanced/68-observability.md b/documentation/docs/30-advanced/68-observability.md index c42878b84697..48d22fb27f49 100644 --- a/documentation/docs/30-advanced/68-observability.md +++ b/documentation/docs/30-advanced/68-observability.md @@ -10,30 +10,30 @@ title: Observability Sometimes, you may need to observe how your application is behaving in order to improve performance or find the root cause of a pesky bug. To help with this, SvelteKit can emit server-side [OpenTelemetry](https://opentelemetry.io) spans for the following: -- [`handle`](hooks#Server-hooks-handle) hook (`handle` functions running in a [`sequence`](@sveltejs-kit-hooks#sequence) will show up as children of each other and the root handle hook) +- [`handle`](hooks#Server-hooks-handle) hook (`handle` functions running in a [`sequence`](@sveltejs-kit-hooks#sequence) will show up as children of each other and the root handle hook) - [`load`](load) functions (includes universal `load` functions when they're run on the server) - [Form actions](form-actions) - [Remote functions](remote-functions) -Just telling SvelteKit to emit spans won't get you far, though -- you need to actually collect them somewhere to be able to view them. SvelteKit provides `src/tracing.server.ts` as a place to write your tracing setup and instrumentation code. It's guaranteed to be run prior to your application code being imported, providing your deployment platform supports it and your adapter is aware of it. +Just telling SvelteKit to emit spans won't get you far, though — you need to actually collect them somewhere to be able to view them. SvelteKit provides `src/tracing.server.ts` as a place to write your tracing setup and instrumentation code. It's guaranteed to be run prior to your application code being imported, providing your deployment platform supports it and your adapter is aware of it. To enable both of these features, add the following to your `svelte.config.js`: -```js -/// file: svelte.config.js -export default { - kit: { - +++experimental: { - tracing: { - server: true, - serverFile: true - } - }+++ - } -}; +```js +/// file: svelte.config.js +export default { + kit: { + +++experimental: { + tracing: { + server: true, + serverFile: true + } + }+++ + } +}; ``` -> [!NOTE] Tracing -- and more significantly, tracing instrumentation -- can have a nontrivial overhead. Before you go all-in on tracing, consider whether or not you really need it, or if it might be more appropriate to turn it on in development and preview environments only. +> [!NOTE] Tracing — and more significantly, tracing instrumentation — can have a nontrivial overhead. Before you go all-in on tracing, consider whether or not you really need it, or if it might be more appropriate to turn it on in development and preview environments only. ## Development quickstart From 71b4cdd2c253b24f014c32901a7a44e65fcde724 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 13 Aug 2025 11:09:30 -0400 Subject: [PATCH 58/74] Update packages/kit/src/exports/public.d.ts Co-authored-by: Tee Ming --- packages/kit/src/exports/public.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 6c4c12eec6ee..bb5dfb443c60 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -460,7 +460,7 @@ export interface KitConfig { /** Experimental features. Here be dragons. These are not subject to semantic versioning, so breaking changes or removal can happen in any release. */ experimental?: { /** - * Options for enabling to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). + * Options to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). * @default { server: false, serverFile: false } * @since 2.29.0 */ From d15b9f5ca505003b8ee9c576015f6390512c0837 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 13 Aug 2025 11:25:11 -0400 Subject: [PATCH 59/74] bump since tags --- packages/kit/src/exports/public.d.ts | 18 +- packages/kit/types/index.d.ts | 279 ++++++++++++++++++--------- 2 files changed, 201 insertions(+), 96 deletions(-) diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index bb5dfb443c60..22285014a1bf 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -55,7 +55,7 @@ export interface Adapter { /** * Test support for `tracing`. To pass, the adapter must support `tracing.server.js` and * also deploy to a platform that supports `@opentelemetry/api`. - * @since 2.29.0 + * @since 2.30.0 */ tracing?: () => boolean; }; @@ -198,7 +198,7 @@ export interface Builder { /** * Check if the server tracing file exists. * @returns true if the server tracing file exists, false otherwise - * @since 2.29.0 + * @since 2.30.0 */ hasServerTracingFile: () => boolean; @@ -221,7 +221,7 @@ export interface Builder { * @param options.module configuration for the resulting entrypoint module. * @param options.module.exports * @param options.module.generateText a function that receives the relative paths to the tracing and start files, and generates the text of the module to be traced. If not provided, the default implementation will be used, which uses top-level await. - * @since 2.29.0 + * @since 2.30.0 */ trace: (args: { entrypoint: string; @@ -462,20 +462,20 @@ export interface KitConfig { /** * Options to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). * @default { server: false, serverFile: false } - * @since 2.29.0 + * @since 2.30.0 */ tracing?: { /** * Enables server-side [OpenTelemetry](https://opentelemetry.io/) span emission for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). * @default false - * @since 2.29.0 + * @since 2.30.0 */ server?: boolean; /** * Enables `tracing.server.js` for tracing instrumentation. * @default false - * @since 2.29.0 + * @since 2.30.0 */ serverFile?: boolean; }; @@ -1063,7 +1063,7 @@ export interface LoadEvent< /** * Access to spans for tracing. If tracing is not enabled or the function is being run in the browser, these spans will do nothing. - * @since 2.29.0 + * @since 2.30.0 */ tracing: { /** Whether tracing is enabled. */ @@ -1354,7 +1354,7 @@ export interface RequestEvent< /** * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.29.0 + * @since 2.30.0 */ tracing: { /** Whether tracing is enabled. */ @@ -1531,7 +1531,7 @@ export interface ServerLoadEvent< /** * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.29.0 + * @since 2.30.0 */ tracing: { /** Whether tracing is enabled. */ diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index d18c7107368d..1249257bc69b 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -4,7 +4,11 @@ declare module '@sveltejs/kit' { import type { SvelteConfig } from '@sveltejs/vite-plugin-svelte'; import type { StandardSchemaV1 } from '@standard-schema/spec'; - import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams, ResolvedPathname } from '$app/types'; + import type { + RouteId as AppRouteId, + LayoutParams as AppLayoutParams, + ResolvedPathname + } from '$app/types'; import type { Span } from '@opentelemetry/api'; /** * [Adapters](https://svelte.dev/docs/kit/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. @@ -32,7 +36,7 @@ declare module '@sveltejs/kit' { /** * Test support for `tracing`. To pass, the adapter must support `tracing.server.js` and * also deploy to a platform that supports `@opentelemetry/api`. - * @since 2.29.0 + * @since 2.30.0 */ tracing?: () => boolean; }; @@ -175,7 +179,7 @@ declare module '@sveltejs/kit' { /** * Check if the server tracing file exists. * @returns true if the server tracing file exists, false otherwise - * @since 2.29.0 + * @since 2.30.0 */ hasServerTracingFile: () => boolean; @@ -197,7 +201,7 @@ declare module '@sveltejs/kit' { * @param options.start the name of the start file. This is what `entrypoint` will be renamed to. * @param options.module configuration for the resulting entrypoint module. * @param options.module.generateText a function that receives the relative paths to the tracing and start files, and generates the text of the module to be traced. If not provided, the default implementation will be used, which uses top-level await. - * @since 2.29.0 + * @since 2.30.0 */ trace: (args: { entrypoint: string; @@ -270,7 +274,10 @@ declare module '@sveltejs/kit' { * @param name the name of the cookie * @param opts the options, passed directly to `cookie.serialize`. The `path` must match the path of the cookie you want to delete. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) */ - delete: (name: string, opts: import('cookie').CookieSerializeOptions & { path: string }) => void; + delete: ( + name: string, + opts: import('cookie').CookieSerializeOptions & { path: string } + ) => void; /** * Serialize a cookie name-value pair into a `Set-Cookie` header string, but don't apply it to the response. @@ -438,20 +445,20 @@ declare module '@sveltejs/kit' { /** * Options for enabling to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). * @default { server: false, serverFile: false } - * @since 2.29.0 + * @since 2.30.0 */ tracing?: { /** * Enables server-side [OpenTelemetry](https://opentelemetry.io/) span emission for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). * @default false - * @since 2.29.0 + * @since 2.30.0 */ server?: boolean; /** * Enables `tracing.server.js` for tracing instrumentation. * @default false - * @since 2.29.0 + * @since 2.30.0 */ serverFile?: boolean; }; @@ -1039,7 +1046,7 @@ declare module '@sveltejs/kit' { /** * Access to spans for tracing. If tracing is not enabled or the function is being run in the browser, these spans will do nothing. - * @since 2.29.0 + * @since 2.30.0 */ tracing: { /** Whether tracing is enabled. */ @@ -1330,7 +1337,7 @@ declare module '@sveltejs/kit' { /** * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.29.0 + * @since 2.30.0 */ tracing: { /** Whether tracing is enabled. */ @@ -1365,7 +1372,10 @@ declare module '@sveltejs/kit' { * but they will always be split at sensible boundaries such as `%sveltekit.head%` or layout/page components. * @param input the html chunk and the info if this is the last chunk */ - transformPageChunk?: (input: { html: string; done: boolean }) => MaybePromise; + transformPageChunk?: (input: { + html: string; + done: boolean; + }) => MaybePromise; /** * Determines which headers should be included in serialized responses when a `load` function loads a resource with `fetch`. * By default, none will be included. @@ -1507,7 +1517,7 @@ declare module '@sveltejs/kit' { /** * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.29.0 + * @since 2.30.0 */ tracing: { /** Whether tracing is enabled. */ @@ -1775,7 +1785,9 @@ declare module '@sveltejs/kit' { * A function that is invoked once the entry has been created. This is where you * should write the function to the filesystem and generate redirect manifests. */ - complete(entry: { generateManifest(opts: { relativePath: string }): string }): MaybePromise; + complete(entry: { + generateManifest(opts: { relativePath: string }): string; + }): MaybePromise; } // Based on https://github.com/josh-hemphill/csp-typed-directives/blob/latest/src/csp.types.ts @@ -2231,16 +2243,24 @@ declare module '@sveltejs/kit' { * @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling. * @throws {Error} If the provided status is invalid (not between 400 and 599). */ - export function error(status: number, body?: { - message: string; - } extends App.Error ? App.Error | string | undefined : never): never; + export function error( + status: number, + body?: { + message: string; + } extends App.Error + ? App.Error | string | undefined + : never + ): never; /** * Checks whether this is an error thrown by {@link error}. * @param status The status to filter for. * */ - export function isHttpError(e: unknown, status?: T): e is (HttpError_1 & { + export function isHttpError( + e: unknown, + status?: T + ): e is HttpError_1 & { status: T extends undefined ? never : T; - }); + }; /** * Redirect a request. When called during request handling, SvelteKit will return a redirect response. * Make sure you're not catching the thrown redirect, which would prevent SvelteKit from handling it. @@ -2257,7 +2277,10 @@ declare module '@sveltejs/kit' { * @throws {Redirect} This error instructs SvelteKit to redirect to the specified location. * @throws {Error} If the provided status is invalid. * */ - export function redirect(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number), location: string | URL): never; + export function redirect( + status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number), + location: string | URL + ): never; /** * Checks whether this is a redirect thrown by {@link redirect}. * @param e The object to check. @@ -2309,20 +2332,31 @@ declare module '@sveltejs/kit' { wasNormalized: boolean; denormalize: (url?: string | URL) => URL; }; - export type LessThan = TNumber extends TArray["length"] ? TArray[number] : LessThan; - export type NumericRange = Exclude, LessThan>; + export type LessThan< + TNumber extends number, + TArray extends any[] = [] + > = TNumber extends TArray['length'] + ? TArray[number] + : LessThan; + export type NumericRange = Exclude< + TEnd | LessThan, + LessThan + >; export const VERSION: string; class HttpError_1 { - - constructor(status: number, body: { - message: string; - } extends App.Error ? (App.Error | string | undefined) : App.Error); + constructor( + status: number, + body: { + message: string; + } extends App.Error + ? App.Error | string | undefined + : App.Error + ); status: number; body: App.Error; toString(): string; } class Redirect_1 { - constructor(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308, location: string); status: 301 | 302 | 303 | 307 | 308 | 300 | 304 | 305 | 306; location: string; @@ -2409,13 +2443,20 @@ declare module '@sveltejs/kit/hooks' { } declare module '@sveltejs/kit/node' { - export function getRequest({ request, base, bodySizeLimit }: { - request: import("http").IncomingMessage; + export function getRequest({ + request, + base, + bodySizeLimit + }: { + request: import('http').IncomingMessage; base: string; bodySizeLimit?: number; }): Promise; - export function setResponse(res: import("http").ServerResponse, response: Response): Promise; + export function setResponse( + res: import('http').ServerResponse, + response: Response + ): Promise; /** * Converts a file on disk to a readable stream * @since 2.4.0 @@ -2440,7 +2481,7 @@ declare module '@sveltejs/kit/vite' { /** * Returns the SvelteKit Vite plugins. * */ - export function sveltekit(): Promise; + export function sveltekit(): Promise; export {}; } @@ -2488,7 +2529,10 @@ declare module '$app/forms' { * } * ``` * */ - export function deserialize | undefined, Failure extends Record | undefined>(result: string): import("@sveltejs/kit").ActionResult; + export function deserialize< + Success extends Record | undefined, + Failure extends Record | undefined + >(result: string): import('@sveltejs/kit').ActionResult; /** * This action enhances a `` element that otherwise would work without JavaScript. * @@ -2512,14 +2556,23 @@ declare module '$app/forms' { * @param form_element The form element * @param submit Submit callback */ - export function enhance | undefined, Failure extends Record | undefined>(form_element: HTMLFormElement, submit?: import("@sveltejs/kit").SubmitFunction): { + export function enhance< + Success extends Record | undefined, + Failure extends Record | undefined + >( + form_element: HTMLFormElement, + submit?: import('@sveltejs/kit').SubmitFunction + ): { destroy(): void; }; /** * This action updates the `form` property of the current page with the given data and updates `page.status`. * In case of an error, it redirects to the nearest error page. * */ - export function applyAction | undefined, Failure extends Record | undefined>(result: import("@sveltejs/kit").ActionResult): Promise; + export function applyAction< + Success extends Record | undefined, + Failure extends Record | undefined + >(result: import('@sveltejs/kit').ActionResult): Promise; export {}; } @@ -2530,7 +2583,9 @@ declare module '$app/navigation' { * * `afterNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function afterNavigate(callback: (navigation: import("@sveltejs/kit").AfterNavigate) => void): void; + export function afterNavigate( + callback: (navigation: import('@sveltejs/kit').AfterNavigate) => void + ): void; /** * A navigation interceptor that triggers before we navigate to a URL, whether by clicking a link, calling `goto(...)`, or using the browser back/forward controls. * @@ -2542,7 +2597,9 @@ declare module '$app/navigation' { * * `beforeNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function beforeNavigate(callback: (navigation: import("@sveltejs/kit").BeforeNavigate) => void): void; + export function beforeNavigate( + callback: (navigation: import('@sveltejs/kit').BeforeNavigate) => void + ): void; /** * A lifecycle function that runs the supplied `callback` immediately before we navigate to a new URL except during full-page navigations. * @@ -2552,7 +2609,9 @@ declare module '$app/navigation' { * * `onNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function onNavigate(callback: (navigation: import("@sveltejs/kit").OnNavigate) => MaybePromise<(() => void) | void>): void; + export function onNavigate( + callback: (navigation: import('@sveltejs/kit').OnNavigate) => MaybePromise<(() => void) | void> + ): void; /** * If called when the page is being updated following a navigation (in `onMount` or `afterNavigate` or an action, for example), this disables SvelteKit's built-in scroll handling. * This is generally discouraged, since it breaks user expectations. @@ -2567,14 +2626,17 @@ declare module '$app/navigation' { * @param url Where to navigate to. Note that if you've set [`config.kit.paths.base`](https://svelte.dev/docs/kit/configuration#paths) and the URL is root-relative, you need to prepend the base path if you want to navigate within the app. * @param {Object} opts Options related to the navigation * */ - export function goto(url: string | URL, opts?: { - replaceState?: boolean | undefined; - noScroll?: boolean | undefined; - keepFocus?: boolean | undefined; - invalidateAll?: boolean | undefined; - invalidate?: (string | URL | ((url: URL) => boolean))[] | undefined; - state?: App.PageState | undefined; - }): Promise; + export function goto( + url: string | URL, + opts?: { + replaceState?: boolean | undefined; + noScroll?: boolean | undefined; + keepFocus?: boolean | undefined; + invalidateAll?: boolean | undefined; + invalidate?: (string | URL | ((url: URL) => boolean))[] | undefined; + state?: App.PageState | undefined; + } + ): Promise; /** * Causes any `load` functions belonging to the currently active page to re-run if they depend on the `url` in question, via `fetch` or `depends`. Returns a `Promise` that resolves when the page is subsequently updated. * @@ -2601,7 +2663,9 @@ declare module '$app/navigation' { * Causes all currently active remote functions to refresh, and all `load` functions belonging to the currently active page to re-run (unless disabled via the option argument). * Returns a `Promise` that resolves when the page is subsequently updated. * */ - export function refreshAll({ includeLoadFunctions }?: { + export function refreshAll({ + includeLoadFunctions + }?: { includeLoadFunctions?: boolean; }): Promise; /** @@ -2615,14 +2679,17 @@ declare module '$app/navigation' { * * @param href Page to preload * */ - export function preloadData(href: string): Promise<{ - type: "loaded"; - status: number; - data: Record; - } | { - type: "redirect"; - location: string; - }>; + export function preloadData(href: string): Promise< + | { + type: 'loaded'; + status: number; + data: Record; + } + | { + type: 'redirect'; + location: string; + } + >; /** * Programmatically imports the code for routes that haven't yet been fetched. * Typically, you might call this to speed up subsequent navigation. @@ -2724,7 +2791,13 @@ declare module '$app/paths' { } declare module '$app/server' { - import type { RequestEvent, RemoteCommand, RemoteForm, RemotePrerenderFunction, RemoteQueryFunction } from '@sveltejs/kit'; + import type { + RequestEvent, + RemoteCommand, + RemoteForm, + RemotePrerenderFunction, + RemoteQueryFunction + } from '@sveltejs/kit'; import type { StandardSchemaV1 } from '@standard-schema/spec'; /** * Read the contents of an imported asset from the filesystem @@ -2761,7 +2834,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function command(validate: "unchecked", fn: (arg: Input) => Output): RemoteCommand; + export function command( + validate: 'unchecked', + fn: (arg: Input) => Output + ): RemoteCommand; /** * Creates a remote command. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2769,7 +2845,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function command(validate: Schema, fn: (arg: StandardSchemaV1.InferOutput) => Output): RemoteCommand, Output>; + export function command( + validate: Schema, + fn: (arg: StandardSchemaV1.InferOutput) => Output + ): RemoteCommand, Output>; /** * Creates a form object that can be spread onto a `` element. * @@ -2785,10 +2864,15 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender(fn: () => MaybePromise, options?: { - inputs?: RemotePrerenderInputsGenerator; - dynamic?: boolean; - } | undefined): RemotePrerenderFunction; + export function prerender( + fn: () => MaybePromise, + options?: + | { + inputs?: RemotePrerenderInputsGenerator; + dynamic?: boolean; + } + | undefined + ): RemotePrerenderFunction; /** * Creates a remote prerender function. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2796,10 +2880,16 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender(validate: "unchecked", fn: (arg: Input) => MaybePromise, options?: { - inputs?: RemotePrerenderInputsGenerator; - dynamic?: boolean; - } | undefined): RemotePrerenderFunction; + export function prerender( + validate: 'unchecked', + fn: (arg: Input) => MaybePromise, + options?: + | { + inputs?: RemotePrerenderInputsGenerator; + dynamic?: boolean; + } + | undefined + ): RemotePrerenderFunction; /** * Creates a remote prerender function. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2807,10 +2897,16 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise, options?: { - inputs?: RemotePrerenderInputsGenerator>; - dynamic?: boolean; - } | undefined): RemotePrerenderFunction, Output>; + export function prerender( + schema: Schema, + fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise, + options?: + | { + inputs?: RemotePrerenderInputsGenerator>; + dynamic?: boolean; + } + | undefined + ): RemotePrerenderFunction, Output>; /** * Creates a remote query. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2826,7 +2922,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function query(validate: "unchecked", fn: (arg: Input) => MaybePromise): RemoteQueryFunction; + export function query( + validate: 'unchecked', + fn: (arg: Input) => MaybePromise + ): RemoteQueryFunction; /** * Creates a remote query. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2834,7 +2933,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function query(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise): RemoteQueryFunction, Output>; + export function query( + schema: Schema, + fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise + ): RemoteQueryFunction, Output>; type RemotePrerenderInputsGenerator = () => MaybePromise; type MaybePromise = T | Promise; @@ -2878,19 +2980,21 @@ declare module '$app/state' { * On the server, values can only be read during rendering (in other words _not_ in e.g. `load` functions). In the browser, the values can be read at any time. * * */ - export const page: import("@sveltejs/kit").Page; + export const page: import('@sveltejs/kit').Page; /** * A read-only object representing an in-progress navigation, with `from`, `to`, `type` and (if `type === 'popstate'`) `delta` properties. * Values are `null` when no navigation is occurring, or during server rendering. * */ - export const navigating: import("@sveltejs/kit").Navigation | { - from: null; - to: null; - type: null; - willUnload: null; - delta: null; - complete: null; - }; + export const navigating: + | import('@sveltejs/kit').Navigation + | { + from: null; + to: null; + type: null; + willUnload: null; + delta: null; + complete: null; + }; /** * A read-only reactive value that's initially `false`. If [`version.pollInterval`](https://svelte.dev/docs/kit/configuration#version) is a non-zero value, SvelteKit will poll for new versions of the app and update `current` to `true` when it detects one. `updated.check()` will force an immediate check, regardless of polling. * */ @@ -2904,11 +3008,10 @@ declare module '$app/state' { declare module '$app/stores' { export function getStores(): { - page: typeof page; - + navigating: typeof navigating; - + updated: typeof updated; }; /** @@ -2918,7 +3021,7 @@ declare module '$app/stores' { * * @deprecated Use `page` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const page: import("svelte/store").Readable; + export const page: import('svelte/store').Readable; /** * A readable store. * When navigating starts, its value is a `Navigation` object with `from`, `to`, `type` and (if `type === 'popstate'`) `delta` properties. @@ -2928,7 +3031,9 @@ declare module '$app/stores' { * * @deprecated Use `navigating` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const navigating: import("svelte/store").Readable; + export const navigating: import('svelte/store').Readable< + import('@sveltejs/kit').Navigation | null + >; /** * A readable store whose initial value is `false`. If [`version.pollInterval`](https://svelte.dev/docs/kit/configuration#version) is a non-zero value, SvelteKit will poll for new versions of the app and update the store value to `true` when it detects one. `updated.check()` will force an immediate check, regardless of polling. * @@ -2936,12 +3041,12 @@ declare module '$app/stores' { * * @deprecated Use `updated` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const updated: import("svelte/store").Readable & { + export const updated: import('svelte/store').Readable & { check(): Promise; }; export {}; -}/** +} /** * It's possible to tell SvelteKit how to type objects inside your app by declaring the `App` namespace. By default, a new project will have a file called `src/app.d.ts` containing the following: * * ```ts @@ -3023,4 +3128,4 @@ declare module '$service-worker' { export const version: string; } -//# sourceMappingURL=index.d.ts.map \ No newline at end of file +//# sourceMappingURL=index.d.ts.map From 6edfc8a6184beb4629e88646818d0fcd45437402 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 13 Aug 2025 11:33:20 -0400 Subject: [PATCH 60/74] Apply suggestions from code review --- packages/kit/src/exports/vite/dev/index.js | 2 +- packages/kit/src/exports/vite/index.js | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 23f986c8ebc2..a988a788ed41 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -502,7 +502,7 @@ export async function dev(vite, vite_config, svelte_config) { return; } - const resolved_tracing = resolve_entry(path.resolve(cwd, 'src/tracing.server')); + const resolved_tracing = resolve_entry(path.join(kit.files.src, 'tracing.server')); if (resolved_tracing) { await vite.ssrLoadModule(resolved_tracing); } diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index b4cc82916297..5805741a16e4 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -784,8 +784,7 @@ async function kit({ svelte_config }) { }); // ...and the server tracing file - // TODO: Resolve this however we resolve all of the other files after we deprecate the `files` options - const server_tracing = resolve_entry(path.resolve(cwd, 'src/tracing.server')); + const server_tracing = resolve_entry(path.join(kit.files.src, 'tracing.server')); if (server_tracing) { const { adapter } = kit; if (adapter && !adapter.supports?.tracing?.()) { From b16c01290c54ff9020024dd9b35e44a87356aa66 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 13 Aug 2025 11:36:11 -0400 Subject: [PATCH 61/74] Update packages/kit/src/exports/vite/dev/index.js --- packages/kit/src/exports/vite/dev/index.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index a988a788ed41..89b13eb5a2af 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -394,8 +394,7 @@ export async function dev(vite, vite_config, svelte_config) { file === appTemplate || file === errorTemplate || file.startsWith(serviceWorker) || - file.startsWith(hooks.server) || - file.startsWith(path.resolve(cwd, 'src/tracing.server')) + file.startsWith(hooks.server) ) { sync.server(svelte_config); } From 6a73667224869defd0f2f0d201ebea952284dab2 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 13 Aug 2025 11:43:55 -0400 Subject: [PATCH 62/74] oops --- packages/kit/src/exports/vite/dev/index.js | 5 +- packages/kit/types/index.d.ts | 263 +++++++-------------- 2 files changed, 83 insertions(+), 185 deletions(-) diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index 89b13eb5a2af..e4277ee03d6e 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -501,7 +501,10 @@ export async function dev(vite, vite_config, svelte_config) { return; } - const resolved_tracing = resolve_entry(path.join(kit.files.src, 'tracing.server')); + const resolved_tracing = resolve_entry( + path.join(svelte_config.kit.files.src, 'tracing.server') + ); + if (resolved_tracing) { await vite.ssrLoadModule(resolved_tracing); } diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index efbb409f2f9b..de7635be63a0 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -4,11 +4,7 @@ declare module '@sveltejs/kit' { import type { SvelteConfig } from '@sveltejs/vite-plugin-svelte'; import type { StandardSchemaV1 } from '@standard-schema/spec'; - import type { - RouteId as AppRouteId, - LayoutParams as AppLayoutParams, - ResolvedPathname - } from '$app/types'; + import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams, ResolvedPathname } from '$app/types'; import type { Span } from '@opentelemetry/api'; /** * [Adapters](https://svelte.dev/docs/kit/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. @@ -274,10 +270,7 @@ declare module '@sveltejs/kit' { * @param name the name of the cookie * @param opts the options, passed directly to `cookie.serialize`. The `path` must match the path of the cookie you want to delete. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) */ - delete: ( - name: string, - opts: import('cookie').CookieSerializeOptions & { path: string } - ) => void; + delete: (name: string, opts: import('cookie').CookieSerializeOptions & { path: string }) => void; /** * Serialize a cookie name-value pair into a `Set-Cookie` header string, but don't apply it to the response. @@ -443,7 +436,7 @@ declare module '@sveltejs/kit' { /** Experimental features. Here be dragons. These are not subject to semantic versioning, so breaking changes or removal can happen in any release. */ experimental?: { /** - * Options for enabling to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). + * Options to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). * @default { server: false, serverFile: false } * @since 2.30.0 */ @@ -1390,10 +1383,7 @@ declare module '@sveltejs/kit' { * but they will always be split at sensible boundaries such as `%sveltekit.head%` or layout/page components. * @param input the html chunk and the info if this is the last chunk */ - transformPageChunk?: (input: { - html: string; - done: boolean; - }) => MaybePromise; + transformPageChunk?: (input: { html: string; done: boolean }) => MaybePromise; /** * Determines which headers should be included in serialized responses when a `load` function loads a resource with `fetch`. * By default, none will be included. @@ -1803,9 +1793,7 @@ declare module '@sveltejs/kit' { * A function that is invoked once the entry has been created. This is where you * should write the function to the filesystem and generate redirect manifests. */ - complete(entry: { - generateManifest(opts: { relativePath: string }): string; - }): MaybePromise; + complete(entry: { generateManifest(opts: { relativePath: string }): string }): MaybePromise; } // Based on https://github.com/josh-hemphill/csp-typed-directives/blob/latest/src/csp.types.ts @@ -2261,24 +2249,16 @@ declare module '@sveltejs/kit' { * @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling. * @throws {Error} If the provided status is invalid (not between 400 and 599). */ - export function error( - status: number, - body?: { - message: string; - } extends App.Error - ? App.Error | string | undefined - : never - ): never; + export function error(status: number, body?: { + message: string; + } extends App.Error ? App.Error | string | undefined : never): never; /** * Checks whether this is an error thrown by {@link error}. * @param status The status to filter for. * */ - export function isHttpError( - e: unknown, - status?: T - ): e is HttpError_1 & { + export function isHttpError(e: unknown, status?: T): e is (HttpError_1 & { status: T extends undefined ? never : T; - }; + }); /** * Redirect a request. When called during request handling, SvelteKit will return a redirect response. * Make sure you're not catching the thrown redirect, which would prevent SvelteKit from handling it. @@ -2295,10 +2275,7 @@ declare module '@sveltejs/kit' { * @throws {Redirect} This error instructs SvelteKit to redirect to the specified location. * @throws {Error} If the provided status is invalid. * */ - export function redirect( - status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number), - location: string | URL - ): never; + export function redirect(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number), location: string | URL): never; /** * Checks whether this is a redirect thrown by {@link redirect}. * @param e The object to check. @@ -2350,31 +2327,20 @@ declare module '@sveltejs/kit' { wasNormalized: boolean; denormalize: (url?: string | URL) => URL; }; - export type LessThan< - TNumber extends number, - TArray extends any[] = [] - > = TNumber extends TArray['length'] - ? TArray[number] - : LessThan; - export type NumericRange = Exclude< - TEnd | LessThan, - LessThan - >; + export type LessThan = TNumber extends TArray["length"] ? TArray[number] : LessThan; + export type NumericRange = Exclude, LessThan>; export const VERSION: string; class HttpError_1 { - constructor( - status: number, - body: { - message: string; - } extends App.Error - ? App.Error | string | undefined - : App.Error - ); + + constructor(status: number, body: { + message: string; + } extends App.Error ? (App.Error | string | undefined) : App.Error); status: number; body: App.Error; toString(): string; } class Redirect_1 { + constructor(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308, location: string); status: 301 | 302 | 303 | 307 | 308 | 300 | 304 | 305 | 306; location: string; @@ -2461,20 +2427,13 @@ declare module '@sveltejs/kit/hooks' { } declare module '@sveltejs/kit/node' { - export function getRequest({ - request, - base, - bodySizeLimit - }: { - request: import('http').IncomingMessage; + export function getRequest({ request, base, bodySizeLimit }: { + request: import("http").IncomingMessage; base: string; bodySizeLimit?: number; }): Promise; - export function setResponse( - res: import('http').ServerResponse, - response: Response - ): Promise; + export function setResponse(res: import("http").ServerResponse, response: Response): Promise; /** * Converts a file on disk to a readable stream * @since 2.4.0 @@ -2499,7 +2458,7 @@ declare module '@sveltejs/kit/vite' { /** * Returns the SvelteKit Vite plugins. * */ - export function sveltekit(): Promise; + export function sveltekit(): Promise; export {}; } @@ -2547,10 +2506,7 @@ declare module '$app/forms' { * } * ``` * */ - export function deserialize< - Success extends Record | undefined, - Failure extends Record | undefined - >(result: string): import('@sveltejs/kit').ActionResult; + export function deserialize | undefined, Failure extends Record | undefined>(result: string): import("@sveltejs/kit").ActionResult; /** * This action enhances a `` element that otherwise would work without JavaScript. * @@ -2574,23 +2530,14 @@ declare module '$app/forms' { * @param form_element The form element * @param submit Submit callback */ - export function enhance< - Success extends Record | undefined, - Failure extends Record | undefined - >( - form_element: HTMLFormElement, - submit?: import('@sveltejs/kit').SubmitFunction - ): { + export function enhance | undefined, Failure extends Record | undefined>(form_element: HTMLFormElement, submit?: import("@sveltejs/kit").SubmitFunction): { destroy(): void; }; /** * This action updates the `form` property of the current page with the given data and updates `page.status`. * In case of an error, it redirects to the nearest error page. * */ - export function applyAction< - Success extends Record | undefined, - Failure extends Record | undefined - >(result: import('@sveltejs/kit').ActionResult): Promise; + export function applyAction | undefined, Failure extends Record | undefined>(result: import("@sveltejs/kit").ActionResult): Promise; export {}; } @@ -2601,9 +2548,7 @@ declare module '$app/navigation' { * * `afterNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function afterNavigate( - callback: (navigation: import('@sveltejs/kit').AfterNavigate) => void - ): void; + export function afterNavigate(callback: (navigation: import("@sveltejs/kit").AfterNavigate) => void): void; /** * A navigation interceptor that triggers before we navigate to a URL, whether by clicking a link, calling `goto(...)`, or using the browser back/forward controls. * @@ -2615,9 +2560,7 @@ declare module '$app/navigation' { * * `beforeNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function beforeNavigate( - callback: (navigation: import('@sveltejs/kit').BeforeNavigate) => void - ): void; + export function beforeNavigate(callback: (navigation: import("@sveltejs/kit").BeforeNavigate) => void): void; /** * A lifecycle function that runs the supplied `callback` immediately before we navigate to a new URL except during full-page navigations. * @@ -2627,9 +2570,7 @@ declare module '$app/navigation' { * * `onNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function onNavigate( - callback: (navigation: import('@sveltejs/kit').OnNavigate) => MaybePromise<(() => void) | void> - ): void; + export function onNavigate(callback: (navigation: import("@sveltejs/kit").OnNavigate) => MaybePromise<(() => void) | void>): void; /** * If called when the page is being updated following a navigation (in `onMount` or `afterNavigate` or an action, for example), this disables SvelteKit's built-in scroll handling. * This is generally discouraged, since it breaks user expectations. @@ -2644,17 +2585,14 @@ declare module '$app/navigation' { * @param url Where to navigate to. Note that if you've set [`config.kit.paths.base`](https://svelte.dev/docs/kit/configuration#paths) and the URL is root-relative, you need to prepend the base path if you want to navigate within the app. * @param {Object} opts Options related to the navigation * */ - export function goto( - url: string | URL, - opts?: { - replaceState?: boolean | undefined; - noScroll?: boolean | undefined; - keepFocus?: boolean | undefined; - invalidateAll?: boolean | undefined; - invalidate?: (string | URL | ((url: URL) => boolean))[] | undefined; - state?: App.PageState | undefined; - } - ): Promise; + export function goto(url: string | URL, opts?: { + replaceState?: boolean | undefined; + noScroll?: boolean | undefined; + keepFocus?: boolean | undefined; + invalidateAll?: boolean | undefined; + invalidate?: (string | URL | ((url: URL) => boolean))[] | undefined; + state?: App.PageState | undefined; + }): Promise; /** * Causes any `load` functions belonging to the currently active page to re-run if they depend on the `url` in question, via `fetch` or `depends`. Returns a `Promise` that resolves when the page is subsequently updated. * @@ -2681,9 +2619,7 @@ declare module '$app/navigation' { * Causes all currently active remote functions to refresh, and all `load` functions belonging to the currently active page to re-run (unless disabled via the option argument). * Returns a `Promise` that resolves when the page is subsequently updated. * */ - export function refreshAll({ - includeLoadFunctions - }?: { + export function refreshAll({ includeLoadFunctions }?: { includeLoadFunctions?: boolean; }): Promise; /** @@ -2697,17 +2633,14 @@ declare module '$app/navigation' { * * @param href Page to preload * */ - export function preloadData(href: string): Promise< - | { - type: 'loaded'; - status: number; - data: Record; - } - | { - type: 'redirect'; - location: string; - } - >; + export function preloadData(href: string): Promise<{ + type: "loaded"; + status: number; + data: Record; + } | { + type: "redirect"; + location: string; + }>; /** * Programmatically imports the code for routes that haven't yet been fetched. * Typically, you might call this to speed up subsequent navigation. @@ -2809,13 +2742,7 @@ declare module '$app/paths' { } declare module '$app/server' { - import type { - RequestEvent, - RemoteCommand, - RemoteForm, - RemotePrerenderFunction, - RemoteQueryFunction - } from '@sveltejs/kit'; + import type { RequestEvent, RemoteCommand, RemoteForm, RemotePrerenderFunction, RemoteQueryFunction } from '@sveltejs/kit'; import type { StandardSchemaV1 } from '@standard-schema/spec'; /** * Read the contents of an imported asset from the filesystem @@ -2852,10 +2779,7 @@ declare module '$app/server' { * * @since 2.27 */ - export function command( - validate: 'unchecked', - fn: (arg: Input) => Output - ): RemoteCommand; + export function command(validate: "unchecked", fn: (arg: Input) => Output): RemoteCommand; /** * Creates a remote command. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2863,10 +2787,7 @@ declare module '$app/server' { * * @since 2.27 */ - export function command( - validate: Schema, - fn: (arg: StandardSchemaV1.InferOutput) => Output - ): RemoteCommand, Output>; + export function command(validate: Schema, fn: (arg: StandardSchemaV1.InferOutput) => Output): RemoteCommand, Output>; /** * Creates a form object that can be spread onto a `` element. * @@ -2882,15 +2803,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender( - fn: () => MaybePromise, - options?: - | { - inputs?: RemotePrerenderInputsGenerator; - dynamic?: boolean; - } - | undefined - ): RemotePrerenderFunction; + export function prerender(fn: () => MaybePromise, options?: { + inputs?: RemotePrerenderInputsGenerator; + dynamic?: boolean; + } | undefined): RemotePrerenderFunction; /** * Creates a remote prerender function. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2898,16 +2814,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender( - validate: 'unchecked', - fn: (arg: Input) => MaybePromise, - options?: - | { - inputs?: RemotePrerenderInputsGenerator; - dynamic?: boolean; - } - | undefined - ): RemotePrerenderFunction; + export function prerender(validate: "unchecked", fn: (arg: Input) => MaybePromise, options?: { + inputs?: RemotePrerenderInputsGenerator; + dynamic?: boolean; + } | undefined): RemotePrerenderFunction; /** * Creates a remote prerender function. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2915,16 +2825,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender( - schema: Schema, - fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise, - options?: - | { - inputs?: RemotePrerenderInputsGenerator>; - dynamic?: boolean; - } - | undefined - ): RemotePrerenderFunction, Output>; + export function prerender(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise, options?: { + inputs?: RemotePrerenderInputsGenerator>; + dynamic?: boolean; + } | undefined): RemotePrerenderFunction, Output>; /** * Creates a remote query. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2940,10 +2844,7 @@ declare module '$app/server' { * * @since 2.27 */ - export function query( - validate: 'unchecked', - fn: (arg: Input) => MaybePromise - ): RemoteQueryFunction; + export function query(validate: "unchecked", fn: (arg: Input) => MaybePromise): RemoteQueryFunction; /** * Creates a remote query. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2951,10 +2852,7 @@ declare module '$app/server' { * * @since 2.27 */ - export function query( - schema: Schema, - fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise - ): RemoteQueryFunction, Output>; + export function query(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise): RemoteQueryFunction, Output>; type RemotePrerenderInputsGenerator = () => MaybePromise; type MaybePromise = T | Promise; @@ -2998,21 +2896,19 @@ declare module '$app/state' { * On the server, values can only be read during rendering (in other words _not_ in e.g. `load` functions). In the browser, the values can be read at any time. * * */ - export const page: import('@sveltejs/kit').Page; + export const page: import("@sveltejs/kit").Page; /** * A read-only object representing an in-progress navigation, with `from`, `to`, `type` and (if `type === 'popstate'`) `delta` properties. * Values are `null` when no navigation is occurring, or during server rendering. * */ - export const navigating: - | import('@sveltejs/kit').Navigation - | { - from: null; - to: null; - type: null; - willUnload: null; - delta: null; - complete: null; - }; + export const navigating: import("@sveltejs/kit").Navigation | { + from: null; + to: null; + type: null; + willUnload: null; + delta: null; + complete: null; + }; /** * A read-only reactive value that's initially `false`. If [`version.pollInterval`](https://svelte.dev/docs/kit/configuration#version) is a non-zero value, SvelteKit will poll for new versions of the app and update `current` to `true` when it detects one. `updated.check()` will force an immediate check, regardless of polling. * */ @@ -3026,10 +2922,11 @@ declare module '$app/state' { declare module '$app/stores' { export function getStores(): { + page: typeof page; - + navigating: typeof navigating; - + updated: typeof updated; }; /** @@ -3039,7 +2936,7 @@ declare module '$app/stores' { * * @deprecated Use `page` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const page: import('svelte/store').Readable; + export const page: import("svelte/store").Readable; /** * A readable store. * When navigating starts, its value is a `Navigation` object with `from`, `to`, `type` and (if `type === 'popstate'`) `delta` properties. @@ -3049,9 +2946,7 @@ declare module '$app/stores' { * * @deprecated Use `navigating` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const navigating: import('svelte/store').Readable< - import('@sveltejs/kit').Navigation | null - >; + export const navigating: import("svelte/store").Readable; /** * A readable store whose initial value is `false`. If [`version.pollInterval`](https://svelte.dev/docs/kit/configuration#version) is a non-zero value, SvelteKit will poll for new versions of the app and update the store value to `true` when it detects one. `updated.check()` will force an immediate check, regardless of polling. * @@ -3059,12 +2954,12 @@ declare module '$app/stores' { * * @deprecated Use `updated` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const updated: import('svelte/store').Readable & { + export const updated: import("svelte/store").Readable & { check(): Promise; }; export {}; -} /** +}/** * It's possible to tell SvelteKit how to type objects inside your app by declaring the `App` namespace. By default, a new project will have a file called `src/app.d.ts` containing the following: * * ```ts @@ -3146,4 +3041,4 @@ declare module '$service-worker' { export const version: string; } -//# sourceMappingURL=index.d.ts.map +//# sourceMappingURL=index.d.ts.map \ No newline at end of file From f34728a9f9cd96a84961525eb66dfff20a67d56d Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Wed, 13 Aug 2025 11:53:10 -0400 Subject: [PATCH 63/74] Update documentation/docs/30-advanced/68-observability.md --- documentation/docs/30-advanced/68-observability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/30-advanced/68-observability.md b/documentation/docs/30-advanced/68-observability.md index 48d22fb27f49..24b92c444fa5 100644 --- a/documentation/docs/30-advanced/68-observability.md +++ b/documentation/docs/30-advanced/68-observability.md @@ -40,7 +40,7 @@ export default { To view your first trace, you'll need to set up a local collector. We'll use [Jaeger](https://www.jaegertracing.io/docs/getting-started/) in this example, as they provide an easy-to-use quickstart command. Once your collector is running locally: - Turn on the experimental flag mentioned above in your `svelte.config.js` file -- Use your package manager to install `@opentelemetry/sdk-node`, `@opentelemetry/auto-instrumentations-node`, `@opentelemetry/exporter-trace-otlp-proto`, and `import-in-the-middle` +- Use your package manager to install the dependencies you'll need ```sh npm i @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-oltp-proto import-in-the-middle ``` From ace50a312cda891a0c434d4c62c97b454634605d Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Wed, 13 Aug 2025 11:15:57 -0600 Subject: [PATCH 64/74] fix: type nightmares --- packages/kit/scripts/generate-dts.js | 8 +- packages/kit/src/exports/internal/event.js | 6 +- packages/kit/types/index.d.ts | 197 ++------------------- 3 files changed, 22 insertions(+), 189 deletions(-) diff --git a/packages/kit/scripts/generate-dts.js b/packages/kit/scripts/generate-dts.js index 1af5db6ae96b..e8579ec59054 100644 --- a/packages/kit/scripts/generate-dts.js +++ b/packages/kit/scripts/generate-dts.js @@ -1,5 +1,5 @@ import { createBundle } from 'dts-buddy'; -import { readFileSync, writeFileSync } from 'node:fs'; +import { readFileSync } from 'node:fs'; await createBundle({ output: 'types/index.d.ts', @@ -28,9 +28,3 @@ if (types.includes('__sveltekit/')) { types ); } - -// this is hacky as all hell but it gets the tests passing. might be a bug in dts-buddy? -// prettier-ignore -writeFileSync('./types/index.d.ts', types.replace("declare module '$app/server' {", `declare module '$app/server' { - // @ts-ignore - import { LayoutParams as AppLayoutParams, RouteId as AppRouteId } from '$app/types'`)); diff --git a/packages/kit/src/exports/internal/event.js b/packages/kit/src/exports/internal/event.js index f04ed91f13f2..f884e6ab6407 100644 --- a/packages/kit/src/exports/internal/event.js +++ b/packages/kit/src/exports/internal/event.js @@ -1,9 +1,11 @@ +/** @import { RequestEvent } from '@sveltejs/kit' */ /** @import { RequestStore } from 'types' */ +/** @import { AsyncLocalStorage } from 'node:async_hooks' */ /** @type {RequestStore | null} */ let sync_store = null; -/** @type {import('node:async_hooks').AsyncLocalStorage | null} */ +/** @type {AsyncLocalStorage | null} */ let als; import('node:async_hooks') @@ -19,6 +21,8 @@ import('node:async_hooks') * * In environments without [`AsyncLocalStorage`](https://nodejs.org/api/async_context.html#class-asynclocalstorage), this must be called synchronously (i.e. not after an `await`). * @since 2.20.0 + * + * @returns {RequestEvent} */ export function getRequestEvent() { const event = try_get_request_store()?.event; diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 99971191de53..a51d3bea68ad 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -4,7 +4,7 @@ declare module '@sveltejs/kit' { import type { SvelteConfig } from '@sveltejs/vite-plugin-svelte'; import type { StandardSchemaV1 } from '@standard-schema/spec'; - import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams_1, ResolvedPathname } from '$app/types'; + import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams, ResolvedPathname } from '$app/types'; import type { Span } from '@opentelemetry/api'; /** * [Adapters](https://svelte.dev/docs/kit/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. @@ -919,7 +919,7 @@ declare module '@sveltejs/kit' { * rather than using `Load` directly. */ export type Load< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, InputData extends Record | null = Record | null, ParentData extends Record = Record, OutputData extends Record | void = Record | void, @@ -931,7 +931,7 @@ declare module '@sveltejs/kit' { * rather than using `LoadEvent` directly. */ export interface LoadEvent< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, Data extends Record | null = Record | null, ParentData extends Record = Record, RouteId extends AppRouteId | null = AppRouteId | null @@ -1052,7 +1052,7 @@ declare module '@sveltejs/kit' { } export interface NavigationEvent< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, RouteId extends AppRouteId | null = AppRouteId | null > { /** @@ -1078,7 +1078,7 @@ declare module '@sveltejs/kit' { * Information about the target of a specific navigation. */ export interface NavigationTarget< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, RouteId extends AppRouteId | null = AppRouteId | null > { /** @@ -1195,7 +1195,7 @@ declare module '@sveltejs/kit' { * The shape of the [`page`](https://svelte.dev/docs/kit/$app-state#page) reactive object and the [`$page`](https://svelte.dev/docs/kit/$app-stores) store. */ export interface Page< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, RouteId extends AppRouteId | null = AppRouteId | null > { /** @@ -1243,7 +1243,7 @@ declare module '@sveltejs/kit' { export type ParamMatcher = (param: string) => boolean; export interface RequestEvent< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, RouteId extends AppRouteId | null = AppRouteId | null > { /** @@ -1354,7 +1354,7 @@ declare module '@sveltejs/kit' { * It receives `Params` as the first generic argument, which you can skip by using [generated types](https://svelte.dev/docs/kit/types#Generated-types) instead. */ export type RequestHandler< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, RouteId extends AppRouteId | null = AppRouteId | null > = (event: RequestEvent) => MaybePromise; @@ -1435,14 +1435,14 @@ declare module '@sveltejs/kit' { * rather than using `ServerLoad` directly. */ export type ServerLoad< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, ParentData extends Record = Record, OutputData extends Record | void = Record | void, RouteId extends AppRouteId | null = AppRouteId | null > = (event: ServerLoadEvent) => MaybePromise; export interface ServerLoadEvent< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, ParentData extends Record = Record, RouteId extends AppRouteId | null = AppRouteId | null > extends RequestEvent { @@ -1524,7 +1524,7 @@ declare module '@sveltejs/kit' { * See [form actions](https://svelte.dev/docs/kit/form-actions) for more information. */ export type Action< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, OutputData extends Record | void = Record | void, RouteId extends AppRouteId | null = AppRouteId | null > = (event: RequestEvent) => MaybePromise; @@ -1534,7 +1534,7 @@ declare module '@sveltejs/kit' { * See [form actions](https://svelte.dev/docs/kit/form-actions) for more information. */ export type Actions< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, + Params extends AppLayoutParams<'/'> = AppLayoutParams<'/'>, OutputData extends Record | void = Record | void, RouteId extends AppRouteId | null = AppRouteId | null > = Record>; @@ -2724,12 +2724,8 @@ declare module '$app/paths' { } declare module '$app/server' { - // @ts-ignore - import { LayoutParams as AppLayoutParams, RouteId as AppRouteId } from '$app/types' - import type { RemoteCommand, RemoteForm, RemotePrerenderFunction, RemoteQueryFunction } from '@sveltejs/kit'; + import type { RequestEvent, RemoteCommand, RemoteForm, RemotePrerenderFunction, RemoteQueryFunction } from '@sveltejs/kit'; import type { StandardSchemaV1 } from '@standard-schema/spec'; - import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams_1 } from '$app/types'; - import type { Span } from '@opentelemetry/api'; /** * Read the contents of an imported asset from the filesystem * @example @@ -2748,8 +2744,9 @@ declare module '$app/server' { * * In environments without [`AsyncLocalStorage`](https://nodejs.org/api/async_context.html#class-asynclocalstorage), this must be called synchronously (i.e. not after an `await`). * @since 2.20.0 - */ - export function getRequestEvent(): RequestEvent, any>; + * + * */ + export function getRequestEvent(): RequestEvent; /** * Creates a remote command. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2839,168 +2836,6 @@ declare module '$app/server' { * @since 2.27 */ export function query(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise): RemoteQueryFunction, Output>; - interface Cookies { - /** - * Gets a cookie that was previously set with `cookies.set`, or from the request headers. - * @param name the name of the cookie - * @param opts the options, passed directly to `cookie.parse`. See documentation [here](https://github.com/jshttp/cookie#cookieparsestr-options) - */ - get: (name: string, opts?: import('cookie').CookieParseOptions) => string | undefined; - - /** - * Gets all cookies that were previously set with `cookies.set`, or from the request headers. - * @param opts the options, passed directly to `cookie.parse`. See documentation [here](https://github.com/jshttp/cookie#cookieparsestr-options) - */ - getAll: (opts?: import('cookie').CookieParseOptions) => Array<{ name: string; value: string }>; - - /** - * Sets a cookie. This will add a `set-cookie` header to the response, but also make the cookie available via `cookies.get` or `cookies.getAll` during the current request. - * - * The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`. - * - * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children - * @param name the name of the cookie - * @param value the cookie value - * @param opts the options, passed directly to `cookie.serialize`. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) - */ - set: ( - name: string, - value: string, - opts: import('cookie').CookieSerializeOptions & { path: string } - ) => void; - - /** - * Deletes a cookie by setting its value to an empty string and setting the expiry date in the past. - * - * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children - * @param name the name of the cookie - * @param opts the options, passed directly to `cookie.serialize`. The `path` must match the path of the cookie you want to delete. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) - */ - delete: (name: string, opts: import('cookie').CookieSerializeOptions & { path: string }) => void; - - /** - * Serialize a cookie name-value pair into a `Set-Cookie` header string, but don't apply it to the response. - * - * The `httpOnly` and `secure` options are `true` by default (except on http://localhost, where `secure` is `false`), and must be explicitly disabled if you want cookies to be readable by client-side JavaScript and/or transmitted over HTTP. The `sameSite` option defaults to `lax`. - * - * You must specify a `path` for the cookie. In most cases you should explicitly set `path: '/'` to make the cookie available throughout your app. You can use relative paths, or set `path: ''` to make the cookie only available on the current path and its children - * - * @param name the name of the cookie - * @param value the cookie value - * @param opts the options, passed directly to `cookie.serialize`. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) - */ - serialize: ( - name: string, - value: string, - opts: import('cookie').CookieSerializeOptions & { path: string } - ) => string; - } - - interface RequestEvent< - Params extends AppLayoutParams_1<'/'> = AppLayoutParams_1<'/'>, - RouteId extends AppRouteId | null = AppRouteId | null - > { - /** - * Get or set cookies related to the current request - */ - cookies: Cookies; - /** - * `fetch` is equivalent to the [native `fetch` web API](https://developer.mozilla.org/en-US/docs/Web/API/fetch), with a few additional features: - * - * - It can be used to make credentialed requests on the server, as it inherits the `cookie` and `authorization` headers for the page request. - * - It can make relative requests on the server (ordinarily, `fetch` requires a URL with an origin when used in a server context). - * - Internal requests (e.g. for `+server.js` routes) go directly to the handler function when running on the server, without the overhead of an HTTP call. - * - During server-side rendering, the response will be captured and inlined into the rendered HTML by hooking into the `text` and `json` methods of the `Response` object. Note that headers will _not_ be serialized, unless explicitly included via [`filterSerializedResponseHeaders`](https://svelte.dev/docs/kit/hooks#Server-hooks-handle) - * - During hydration, the response will be read from the HTML, guaranteeing consistency and preventing an additional network request. - * - * You can learn more about making credentialed requests with cookies [here](https://svelte.dev/docs/kit/load#Cookies). - */ - fetch: typeof fetch; - /** - * The client's IP address, set by the adapter. - */ - getClientAddress: () => string; - /** - * Contains custom data that was added to the request within the [`server handle hook`](https://svelte.dev/docs/kit/hooks#Server-hooks-handle). - */ - locals: App.Locals; - /** - * The parameters of the current route - e.g. for a route like `/blog/[slug]`, a `{ slug: string }` object. - */ - params: Params; - /** - * Additional data made available through the adapter. - */ - platform: Readonly | undefined; - /** - * The original request object. - */ - request: Request; - /** - * Info about the current route. - */ - route: { - /** - * The ID of the current route - e.g. for `src/routes/blog/[slug]`, it would be `/blog/[slug]`. It is `null` when no route is matched. - */ - id: RouteId; - }; - /** - * If you need to set headers for the response, you can do so using the this method. This is useful if you want the page to be cached, for example: - * - * ```js - * /// file: src/routes/blog/+page.js - * export async function load({ fetch, setHeaders }) { - * const url = `https://cms.example.com/articles.json`; - * const response = await fetch(url); - * - * setHeaders({ - * age: response.headers.get('age'), - * 'cache-control': response.headers.get('cache-control') - * }); - * - * return response.json(); - * } - * ``` - * - * Setting the same header multiple times (even in separate `load` functions) is an error — you can only set a given header once. - * - * You cannot add a `set-cookie` header with `setHeaders` — use the [`cookies`](https://svelte.dev/docs/kit/@sveltejs-kit#Cookies) API instead. - */ - setHeaders: (headers: Record) => void; - /** - * The requested URL. - */ - url: URL; - /** - * `true` if the request comes from the client asking for `+page/layout.server.js` data. The `url` property will be stripped of the internal information - * related to the data request in this case. Use this property instead if the distinction is important to you. - */ - isDataRequest: boolean; - /** - * `true` for `+server.js` calls coming from SvelteKit without the overhead of actually making an HTTP request. This happens when you make same-origin `fetch` requests on the server. - */ - isSubRequest: boolean; - - /** - * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.29.0 - */ - tracing: { - /** Whether tracing is enabled. */ - enabled: boolean; - /** The root span for the request. This span is named `sveltekit.handle.root`. */ - root: Span; - /** The span associated with the current `handle` hook, `load` function, or form action. */ - current: Span; - }; - - /** - * `true` if the request comes from the client via a remote function. The `url` property will be stripped of the internal information - * related to the data request in this case. Use this property instead if the distinction is important to you. - */ - isRemoteRequest: boolean; - } type RemotePrerenderInputsGenerator = () => MaybePromise; type MaybePromise = T | Promise; From f0acd032967a4edb775d0a1d3fe511010b134c5b Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 14 Aug 2025 10:04:45 -0400 Subject: [PATCH 65/74] bump since tags --- packages/kit/src/exports/public.d.ts | 18 +- packages/kit/types/index.d.ts | 279 ++++++++++++++++++--------- 2 files changed, 201 insertions(+), 96 deletions(-) diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 8f6b52d84c2a..1ed2fc3f4be2 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -55,7 +55,7 @@ export interface Adapter { /** * Test support for `tracing`. To pass, the adapter must support `tracing.server.js` and * also deploy to a platform that supports `@opentelemetry/api`. - * @since 2.30.0 + * @since 2.31.0 */ tracing?: () => boolean; }; @@ -198,7 +198,7 @@ export interface Builder { /** * Check if the server tracing file exists. * @returns true if the server tracing file exists, false otherwise - * @since 2.30.0 + * @since 2.31.0 */ hasServerTracingFile: () => boolean; @@ -221,7 +221,7 @@ export interface Builder { * @param options.module configuration for the resulting entrypoint module. * @param options.module.exports * @param options.module.generateText a function that receives the relative paths to the tracing and start files, and generates the text of the module to be traced. If not provided, the default implementation will be used, which uses top-level await. - * @since 2.30.0 + * @since 2.31.0 */ trace: (args: { entrypoint: string; @@ -462,20 +462,20 @@ export interface KitConfig { /** * Options to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). * @default { server: false, serverFile: false } - * @since 2.30.0 + * @since 2.31.0 */ tracing?: { /** * Enables server-side [OpenTelemetry](https://opentelemetry.io/) span emission for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). * @default false - * @since 2.30.0 + * @since 2.31.0 */ server?: boolean; /** * Enables `tracing.server.js` for tracing instrumentation. * @default false - * @since 2.30.0 + * @since 2.31.0 */ serverFile?: boolean; }; @@ -1081,7 +1081,7 @@ export interface LoadEvent< /** * Access to spans for tracing. If tracing is not enabled or the function is being run in the browser, these spans will do nothing. - * @since 2.30.0 + * @since 2.31.0 */ tracing: { /** Whether tracing is enabled. */ @@ -1372,7 +1372,7 @@ export interface RequestEvent< /** * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.30.0 + * @since 2.31.0 */ tracing: { /** Whether tracing is enabled. */ @@ -1549,7 +1549,7 @@ export interface ServerLoadEvent< /** * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.30.0 + * @since 2.31.0 */ tracing: { /** Whether tracing is enabled. */ diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index d48c32bd494c..a363df6455e5 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -4,7 +4,11 @@ declare module '@sveltejs/kit' { import type { SvelteConfig } from '@sveltejs/vite-plugin-svelte'; import type { StandardSchemaV1 } from '@standard-schema/spec'; - import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams, ResolvedPathname } from '$app/types'; + import type { + RouteId as AppRouteId, + LayoutParams as AppLayoutParams, + ResolvedPathname + } from '$app/types'; import type { Span } from '@opentelemetry/api'; /** * [Adapters](https://svelte.dev/docs/kit/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. @@ -32,7 +36,7 @@ declare module '@sveltejs/kit' { /** * Test support for `tracing`. To pass, the adapter must support `tracing.server.js` and * also deploy to a platform that supports `@opentelemetry/api`. - * @since 2.30.0 + * @since 2.31.0 */ tracing?: () => boolean; }; @@ -175,7 +179,7 @@ declare module '@sveltejs/kit' { /** * Check if the server tracing file exists. * @returns true if the server tracing file exists, false otherwise - * @since 2.30.0 + * @since 2.31.0 */ hasServerTracingFile: () => boolean; @@ -197,7 +201,7 @@ declare module '@sveltejs/kit' { * @param options.start the name of the start file. This is what `entrypoint` will be renamed to. * @param options.module configuration for the resulting entrypoint module. * @param options.module.generateText a function that receives the relative paths to the tracing and start files, and generates the text of the module to be traced. If not provided, the default implementation will be used, which uses top-level await. - * @since 2.30.0 + * @since 2.31.0 */ trace: (args: { entrypoint: string; @@ -270,7 +274,10 @@ declare module '@sveltejs/kit' { * @param name the name of the cookie * @param opts the options, passed directly to `cookie.serialize`. The `path` must match the path of the cookie you want to delete. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) */ - delete: (name: string, opts: import('cookie').CookieSerializeOptions & { path: string }) => void; + delete: ( + name: string, + opts: import('cookie').CookieSerializeOptions & { path: string } + ) => void; /** * Serialize a cookie name-value pair into a `Set-Cookie` header string, but don't apply it to the response. @@ -438,20 +445,20 @@ declare module '@sveltejs/kit' { /** * Options to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). * @default { server: false, serverFile: false } - * @since 2.30.0 + * @since 2.31.0 */ tracing?: { /** * Enables server-side [OpenTelemetry](https://opentelemetry.io/) span emission for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). * @default false - * @since 2.30.0 + * @since 2.31.0 */ server?: boolean; /** * Enables `tracing.server.js` for tracing instrumentation. * @default false - * @since 2.30.0 + * @since 2.31.0 */ serverFile?: boolean; }; @@ -1057,7 +1064,7 @@ declare module '@sveltejs/kit' { /** * Access to spans for tracing. If tracing is not enabled or the function is being run in the browser, these spans will do nothing. - * @since 2.30.0 + * @since 2.31.0 */ tracing: { /** Whether tracing is enabled. */ @@ -1348,7 +1355,7 @@ declare module '@sveltejs/kit' { /** * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.30.0 + * @since 2.31.0 */ tracing: { /** Whether tracing is enabled. */ @@ -1383,7 +1390,10 @@ declare module '@sveltejs/kit' { * but they will always be split at sensible boundaries such as `%sveltekit.head%` or layout/page components. * @param input the html chunk and the info if this is the last chunk */ - transformPageChunk?: (input: { html: string; done: boolean }) => MaybePromise; + transformPageChunk?: (input: { + html: string; + done: boolean; + }) => MaybePromise; /** * Determines which headers should be included in serialized responses when a `load` function loads a resource with `fetch`. * By default, none will be included. @@ -1525,7 +1535,7 @@ declare module '@sveltejs/kit' { /** * Access to spans for tracing. If tracing is not enabled, these spans will do nothing. - * @since 2.30.0 + * @since 2.31.0 */ tracing: { /** Whether tracing is enabled. */ @@ -1793,7 +1803,9 @@ declare module '@sveltejs/kit' { * A function that is invoked once the entry has been created. This is where you * should write the function to the filesystem and generate redirect manifests. */ - complete(entry: { generateManifest(opts: { relativePath: string }): string }): MaybePromise; + complete(entry: { + generateManifest(opts: { relativePath: string }): string; + }): MaybePromise; } // Based on https://github.com/josh-hemphill/csp-typed-directives/blob/latest/src/csp.types.ts @@ -2249,16 +2261,24 @@ declare module '@sveltejs/kit' { * @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling. * @throws {Error} If the provided status is invalid (not between 400 and 599). */ - export function error(status: number, body?: { - message: string; - } extends App.Error ? App.Error | string | undefined : never): never; + export function error( + status: number, + body?: { + message: string; + } extends App.Error + ? App.Error | string | undefined + : never + ): never; /** * Checks whether this is an error thrown by {@link error}. * @param status The status to filter for. * */ - export function isHttpError(e: unknown, status?: T): e is (HttpError_1 & { + export function isHttpError( + e: unknown, + status?: T + ): e is HttpError_1 & { status: T extends undefined ? never : T; - }); + }; /** * Redirect a request. When called during request handling, SvelteKit will return a redirect response. * Make sure you're not catching the thrown redirect, which would prevent SvelteKit from handling it. @@ -2275,7 +2295,10 @@ declare module '@sveltejs/kit' { * @throws {Redirect} This error instructs SvelteKit to redirect to the specified location. * @throws {Error} If the provided status is invalid. * */ - export function redirect(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number), location: string | URL): never; + export function redirect( + status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number), + location: string | URL + ): never; /** * Checks whether this is a redirect thrown by {@link redirect}. * @param e The object to check. @@ -2327,20 +2350,31 @@ declare module '@sveltejs/kit' { wasNormalized: boolean; denormalize: (url?: string | URL) => URL; }; - export type LessThan = TNumber extends TArray["length"] ? TArray[number] : LessThan; - export type NumericRange = Exclude, LessThan>; + export type LessThan< + TNumber extends number, + TArray extends any[] = [] + > = TNumber extends TArray['length'] + ? TArray[number] + : LessThan; + export type NumericRange = Exclude< + TEnd | LessThan, + LessThan + >; export const VERSION: string; class HttpError_1 { - - constructor(status: number, body: { - message: string; - } extends App.Error ? (App.Error | string | undefined) : App.Error); + constructor( + status: number, + body: { + message: string; + } extends App.Error + ? App.Error | string | undefined + : App.Error + ); status: number; body: App.Error; toString(): string; } class Redirect_1 { - constructor(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308, location: string); status: 301 | 302 | 303 | 307 | 308 | 300 | 304 | 305 | 306; location: string; @@ -2427,13 +2461,20 @@ declare module '@sveltejs/kit/hooks' { } declare module '@sveltejs/kit/node' { - export function getRequest({ request, base, bodySizeLimit }: { - request: import("http").IncomingMessage; + export function getRequest({ + request, + base, + bodySizeLimit + }: { + request: import('http').IncomingMessage; base: string; bodySizeLimit?: number; }): Promise; - export function setResponse(res: import("http").ServerResponse, response: Response): Promise; + export function setResponse( + res: import('http').ServerResponse, + response: Response + ): Promise; /** * Converts a file on disk to a readable stream * @since 2.4.0 @@ -2458,7 +2499,7 @@ declare module '@sveltejs/kit/vite' { /** * Returns the SvelteKit Vite plugins. * */ - export function sveltekit(): Promise; + export function sveltekit(): Promise; export {}; } @@ -2506,7 +2547,10 @@ declare module '$app/forms' { * } * ``` * */ - export function deserialize | undefined, Failure extends Record | undefined>(result: string): import("@sveltejs/kit").ActionResult; + export function deserialize< + Success extends Record | undefined, + Failure extends Record | undefined + >(result: string): import('@sveltejs/kit').ActionResult; /** * This action enhances a `` element that otherwise would work without JavaScript. * @@ -2530,14 +2574,23 @@ declare module '$app/forms' { * @param form_element The form element * @param submit Submit callback */ - export function enhance | undefined, Failure extends Record | undefined>(form_element: HTMLFormElement, submit?: import("@sveltejs/kit").SubmitFunction): { + export function enhance< + Success extends Record | undefined, + Failure extends Record | undefined + >( + form_element: HTMLFormElement, + submit?: import('@sveltejs/kit').SubmitFunction + ): { destroy(): void; }; /** * This action updates the `form` property of the current page with the given data and updates `page.status`. * In case of an error, it redirects to the nearest error page. * */ - export function applyAction | undefined, Failure extends Record | undefined>(result: import("@sveltejs/kit").ActionResult): Promise; + export function applyAction< + Success extends Record | undefined, + Failure extends Record | undefined + >(result: import('@sveltejs/kit').ActionResult): Promise; export {}; } @@ -2548,7 +2601,9 @@ declare module '$app/navigation' { * * `afterNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function afterNavigate(callback: (navigation: import("@sveltejs/kit").AfterNavigate) => void): void; + export function afterNavigate( + callback: (navigation: import('@sveltejs/kit').AfterNavigate) => void + ): void; /** * A navigation interceptor that triggers before we navigate to a URL, whether by clicking a link, calling `goto(...)`, or using the browser back/forward controls. * @@ -2560,7 +2615,9 @@ declare module '$app/navigation' { * * `beforeNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function beforeNavigate(callback: (navigation: import("@sveltejs/kit").BeforeNavigate) => void): void; + export function beforeNavigate( + callback: (navigation: import('@sveltejs/kit').BeforeNavigate) => void + ): void; /** * A lifecycle function that runs the supplied `callback` immediately before we navigate to a new URL except during full-page navigations. * @@ -2570,7 +2627,9 @@ declare module '$app/navigation' { * * `onNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function onNavigate(callback: (navigation: import("@sveltejs/kit").OnNavigate) => MaybePromise<(() => void) | void>): void; + export function onNavigate( + callback: (navigation: import('@sveltejs/kit').OnNavigate) => MaybePromise<(() => void) | void> + ): void; /** * If called when the page is being updated following a navigation (in `onMount` or `afterNavigate` or an action, for example), this disables SvelteKit's built-in scroll handling. * This is generally discouraged, since it breaks user expectations. @@ -2585,14 +2644,17 @@ declare module '$app/navigation' { * @param url Where to navigate to. Note that if you've set [`config.kit.paths.base`](https://svelte.dev/docs/kit/configuration#paths) and the URL is root-relative, you need to prepend the base path if you want to navigate within the app. * @param {Object} opts Options related to the navigation * */ - export function goto(url: string | URL, opts?: { - replaceState?: boolean | undefined; - noScroll?: boolean | undefined; - keepFocus?: boolean | undefined; - invalidateAll?: boolean | undefined; - invalidate?: (string | URL | ((url: URL) => boolean))[] | undefined; - state?: App.PageState | undefined; - }): Promise; + export function goto( + url: string | URL, + opts?: { + replaceState?: boolean | undefined; + noScroll?: boolean | undefined; + keepFocus?: boolean | undefined; + invalidateAll?: boolean | undefined; + invalidate?: (string | URL | ((url: URL) => boolean))[] | undefined; + state?: App.PageState | undefined; + } + ): Promise; /** * Causes any `load` functions belonging to the currently active page to re-run if they depend on the `url` in question, via `fetch` or `depends`. Returns a `Promise` that resolves when the page is subsequently updated. * @@ -2619,7 +2681,9 @@ declare module '$app/navigation' { * Causes all currently active remote functions to refresh, and all `load` functions belonging to the currently active page to re-run (unless disabled via the option argument). * Returns a `Promise` that resolves when the page is subsequently updated. * */ - export function refreshAll({ includeLoadFunctions }?: { + export function refreshAll({ + includeLoadFunctions + }?: { includeLoadFunctions?: boolean; }): Promise; /** @@ -2633,14 +2697,17 @@ declare module '$app/navigation' { * * @param href Page to preload * */ - export function preloadData(href: string): Promise<{ - type: "loaded"; - status: number; - data: Record; - } | { - type: "redirect"; - location: string; - }>; + export function preloadData(href: string): Promise< + | { + type: 'loaded'; + status: number; + data: Record; + } + | { + type: 'redirect'; + location: string; + } + >; /** * Programmatically imports the code for routes that haven't yet been fetched. * Typically, you might call this to speed up subsequent navigation. @@ -2742,7 +2809,13 @@ declare module '$app/paths' { } declare module '$app/server' { - import type { RequestEvent, RemoteCommand, RemoteForm, RemotePrerenderFunction, RemoteQueryFunction } from '@sveltejs/kit'; + import type { + RequestEvent, + RemoteCommand, + RemoteForm, + RemotePrerenderFunction, + RemoteQueryFunction + } from '@sveltejs/kit'; import type { StandardSchemaV1 } from '@standard-schema/spec'; /** * Read the contents of an imported asset from the filesystem @@ -2780,7 +2853,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function command(validate: "unchecked", fn: (arg: Input) => Output): RemoteCommand; + export function command( + validate: 'unchecked', + fn: (arg: Input) => Output + ): RemoteCommand; /** * Creates a remote command. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2788,7 +2864,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function command(validate: Schema, fn: (arg: StandardSchemaV1.InferOutput) => Output): RemoteCommand, Output>; + export function command( + validate: Schema, + fn: (arg: StandardSchemaV1.InferOutput) => Output + ): RemoteCommand, Output>; /** * Creates a form object that can be spread onto a `` element. * @@ -2804,10 +2883,15 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender(fn: () => MaybePromise, options?: { - inputs?: RemotePrerenderInputsGenerator; - dynamic?: boolean; - } | undefined): RemotePrerenderFunction; + export function prerender( + fn: () => MaybePromise, + options?: + | { + inputs?: RemotePrerenderInputsGenerator; + dynamic?: boolean; + } + | undefined + ): RemotePrerenderFunction; /** * Creates a remote prerender function. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2815,10 +2899,16 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender(validate: "unchecked", fn: (arg: Input) => MaybePromise, options?: { - inputs?: RemotePrerenderInputsGenerator; - dynamic?: boolean; - } | undefined): RemotePrerenderFunction; + export function prerender( + validate: 'unchecked', + fn: (arg: Input) => MaybePromise, + options?: + | { + inputs?: RemotePrerenderInputsGenerator; + dynamic?: boolean; + } + | undefined + ): RemotePrerenderFunction; /** * Creates a remote prerender function. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2826,10 +2916,16 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise, options?: { - inputs?: RemotePrerenderInputsGenerator>; - dynamic?: boolean; - } | undefined): RemotePrerenderFunction, Output>; + export function prerender( + schema: Schema, + fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise, + options?: + | { + inputs?: RemotePrerenderInputsGenerator>; + dynamic?: boolean; + } + | undefined + ): RemotePrerenderFunction, Output>; /** * Creates a remote query. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2845,7 +2941,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function query(validate: "unchecked", fn: (arg: Input) => MaybePromise): RemoteQueryFunction; + export function query( + validate: 'unchecked', + fn: (arg: Input) => MaybePromise + ): RemoteQueryFunction; /** * Creates a remote query. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2853,7 +2952,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function query(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise): RemoteQueryFunction, Output>; + export function query( + schema: Schema, + fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise + ): RemoteQueryFunction, Output>; type RemotePrerenderInputsGenerator = () => MaybePromise; type MaybePromise = T | Promise; @@ -2897,19 +2999,21 @@ declare module '$app/state' { * On the server, values can only be read during rendering (in other words _not_ in e.g. `load` functions). In the browser, the values can be read at any time. * * */ - export const page: import("@sveltejs/kit").Page; + export const page: import('@sveltejs/kit').Page; /** * A read-only object representing an in-progress navigation, with `from`, `to`, `type` and (if `type === 'popstate'`) `delta` properties. * Values are `null` when no navigation is occurring, or during server rendering. * */ - export const navigating: import("@sveltejs/kit").Navigation | { - from: null; - to: null; - type: null; - willUnload: null; - delta: null; - complete: null; - }; + export const navigating: + | import('@sveltejs/kit').Navigation + | { + from: null; + to: null; + type: null; + willUnload: null; + delta: null; + complete: null; + }; /** * A read-only reactive value that's initially `false`. If [`version.pollInterval`](https://svelte.dev/docs/kit/configuration#version) is a non-zero value, SvelteKit will poll for new versions of the app and update `current` to `true` when it detects one. `updated.check()` will force an immediate check, regardless of polling. * */ @@ -2923,11 +3027,10 @@ declare module '$app/state' { declare module '$app/stores' { export function getStores(): { - page: typeof page; - + navigating: typeof navigating; - + updated: typeof updated; }; /** @@ -2937,7 +3040,7 @@ declare module '$app/stores' { * * @deprecated Use `page` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const page: import("svelte/store").Readable; + export const page: import('svelte/store').Readable; /** * A readable store. * When navigating starts, its value is a `Navigation` object with `from`, `to`, `type` and (if `type === 'popstate'`) `delta` properties. @@ -2947,7 +3050,9 @@ declare module '$app/stores' { * * @deprecated Use `navigating` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const navigating: import("svelte/store").Readable; + export const navigating: import('svelte/store').Readable< + import('@sveltejs/kit').Navigation | null + >; /** * A readable store whose initial value is `false`. If [`version.pollInterval`](https://svelte.dev/docs/kit/configuration#version) is a non-zero value, SvelteKit will poll for new versions of the app and update the store value to `true` when it detects one. `updated.check()` will force an immediate check, regardless of polling. * @@ -2955,12 +3060,12 @@ declare module '$app/stores' { * * @deprecated Use `updated` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const updated: import("svelte/store").Readable & { + export const updated: import('svelte/store').Readable & { check(): Promise; }; export {}; -}/** +} /** * It's possible to tell SvelteKit how to type objects inside your app by declaring the `App` namespace. By default, a new project will have a file called `src/app.d.ts` containing the following: * * ```ts @@ -3042,4 +3147,4 @@ declare module '$service-worker' { export const version: string; } -//# sourceMappingURL=index.d.ts.map \ No newline at end of file +//# sourceMappingURL=index.d.ts.map From 7334888a9ec42403356ab4915b0e48c4e1289252 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 14 Aug 2025 08:12:46 -0600 Subject: [PATCH 66/74] smarter --- packages/kit/src/exports/hooks/sequence.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/kit/src/exports/hooks/sequence.js b/packages/kit/src/exports/hooks/sequence.js index fb152f187422..44f569335f45 100644 --- a/packages/kit/src/exports/hooks/sequence.js +++ b/packages/kit/src/exports/hooks/sequence.js @@ -78,6 +78,7 @@ export function sequence(...handlers) { if (!length) return ({ event, resolve }) => resolve(event); return ({ event, resolve }) => { + const { state } = get_request_store(); return apply_handle(0, event, {}); /** @@ -87,15 +88,14 @@ export function sequence(...handlers) { * @returns {MaybePromise} */ function apply_handle(i, event, parent_options) { - const store = get_request_store(); const handle = handlers[i]; - return store.state.tracing.record_span({ + return state.tracing.record_span({ name: `sveltekit.handle.sequenced.${handle.name ? handle.name : i}`, attributes: {}, fn: async (current) => { const traced_event = merge_tracing(event, current); - return await with_request_store({ event: traced_event, state: store.state }, () => + return await with_request_store({ event: traced_event, state }, () => handle({ event: traced_event, resolve: (event, options) => { From 281cdb4e022bca5e29409fb108e532ad6197f26d Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 14 Aug 2025 08:18:21 -0600 Subject: [PATCH 67/74] types --- packages/kit/types/index.d.ts | 261 ++++++++++------------------------ 1 file changed, 78 insertions(+), 183 deletions(-) diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index a363df6455e5..77f3404da131 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -4,11 +4,7 @@ declare module '@sveltejs/kit' { import type { SvelteConfig } from '@sveltejs/vite-plugin-svelte'; import type { StandardSchemaV1 } from '@standard-schema/spec'; - import type { - RouteId as AppRouteId, - LayoutParams as AppLayoutParams, - ResolvedPathname - } from '$app/types'; + import type { RouteId as AppRouteId, LayoutParams as AppLayoutParams, ResolvedPathname } from '$app/types'; import type { Span } from '@opentelemetry/api'; /** * [Adapters](https://svelte.dev/docs/kit/adapters) are responsible for taking the production build and turning it into something that can be deployed to a platform of your choosing. @@ -274,10 +270,7 @@ declare module '@sveltejs/kit' { * @param name the name of the cookie * @param opts the options, passed directly to `cookie.serialize`. The `path` must match the path of the cookie you want to delete. See documentation [here](https://github.com/jshttp/cookie#cookieserializename-value-options) */ - delete: ( - name: string, - opts: import('cookie').CookieSerializeOptions & { path: string } - ) => void; + delete: (name: string, opts: import('cookie').CookieSerializeOptions & { path: string }) => void; /** * Serialize a cookie name-value pair into a `Set-Cookie` header string, but don't apply it to the response. @@ -1390,10 +1383,7 @@ declare module '@sveltejs/kit' { * but they will always be split at sensible boundaries such as `%sveltekit.head%` or layout/page components. * @param input the html chunk and the info if this is the last chunk */ - transformPageChunk?: (input: { - html: string; - done: boolean; - }) => MaybePromise; + transformPageChunk?: (input: { html: string; done: boolean }) => MaybePromise; /** * Determines which headers should be included in serialized responses when a `load` function loads a resource with `fetch`. * By default, none will be included. @@ -1803,9 +1793,7 @@ declare module '@sveltejs/kit' { * A function that is invoked once the entry has been created. This is where you * should write the function to the filesystem and generate redirect manifests. */ - complete(entry: { - generateManifest(opts: { relativePath: string }): string; - }): MaybePromise; + complete(entry: { generateManifest(opts: { relativePath: string }): string }): MaybePromise; } // Based on https://github.com/josh-hemphill/csp-typed-directives/blob/latest/src/csp.types.ts @@ -2261,24 +2249,16 @@ declare module '@sveltejs/kit' { * @throws {HttpError} This error instructs SvelteKit to initiate HTTP error handling. * @throws {Error} If the provided status is invalid (not between 400 and 599). */ - export function error( - status: number, - body?: { - message: string; - } extends App.Error - ? App.Error | string | undefined - : never - ): never; + export function error(status: number, body?: { + message: string; + } extends App.Error ? App.Error | string | undefined : never): never; /** * Checks whether this is an error thrown by {@link error}. * @param status The status to filter for. * */ - export function isHttpError( - e: unknown, - status?: T - ): e is HttpError_1 & { + export function isHttpError(e: unknown, status?: T): e is (HttpError_1 & { status: T extends undefined ? never : T; - }; + }); /** * Redirect a request. When called during request handling, SvelteKit will return a redirect response. * Make sure you're not catching the thrown redirect, which would prevent SvelteKit from handling it. @@ -2295,10 +2275,7 @@ declare module '@sveltejs/kit' { * @throws {Redirect} This error instructs SvelteKit to redirect to the specified location. * @throws {Error} If the provided status is invalid. * */ - export function redirect( - status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number), - location: string | URL - ): never; + export function redirect(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number), location: string | URL): never; /** * Checks whether this is a redirect thrown by {@link redirect}. * @param e The object to check. @@ -2350,31 +2327,20 @@ declare module '@sveltejs/kit' { wasNormalized: boolean; denormalize: (url?: string | URL) => URL; }; - export type LessThan< - TNumber extends number, - TArray extends any[] = [] - > = TNumber extends TArray['length'] - ? TArray[number] - : LessThan; - export type NumericRange = Exclude< - TEnd | LessThan, - LessThan - >; + export type LessThan = TNumber extends TArray["length"] ? TArray[number] : LessThan; + export type NumericRange = Exclude, LessThan>; export const VERSION: string; class HttpError_1 { - constructor( - status: number, - body: { - message: string; - } extends App.Error - ? App.Error | string | undefined - : App.Error - ); + + constructor(status: number, body: { + message: string; + } extends App.Error ? (App.Error | string | undefined) : App.Error); status: number; body: App.Error; toString(): string; } class Redirect_1 { + constructor(status: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308, location: string); status: 301 | 302 | 303 | 307 | 308 | 300 | 304 | 305 | 306; location: string; @@ -2461,20 +2427,13 @@ declare module '@sveltejs/kit/hooks' { } declare module '@sveltejs/kit/node' { - export function getRequest({ - request, - base, - bodySizeLimit - }: { - request: import('http').IncomingMessage; + export function getRequest({ request, base, bodySizeLimit }: { + request: import("http").IncomingMessage; base: string; bodySizeLimit?: number; }): Promise; - export function setResponse( - res: import('http').ServerResponse, - response: Response - ): Promise; + export function setResponse(res: import("http").ServerResponse, response: Response): Promise; /** * Converts a file on disk to a readable stream * @since 2.4.0 @@ -2499,7 +2458,7 @@ declare module '@sveltejs/kit/vite' { /** * Returns the SvelteKit Vite plugins. * */ - export function sveltekit(): Promise; + export function sveltekit(): Promise; export {}; } @@ -2547,10 +2506,7 @@ declare module '$app/forms' { * } * ``` * */ - export function deserialize< - Success extends Record | undefined, - Failure extends Record | undefined - >(result: string): import('@sveltejs/kit').ActionResult; + export function deserialize | undefined, Failure extends Record | undefined>(result: string): import("@sveltejs/kit").ActionResult; /** * This action enhances a `` element that otherwise would work without JavaScript. * @@ -2574,23 +2530,14 @@ declare module '$app/forms' { * @param form_element The form element * @param submit Submit callback */ - export function enhance< - Success extends Record | undefined, - Failure extends Record | undefined - >( - form_element: HTMLFormElement, - submit?: import('@sveltejs/kit').SubmitFunction - ): { + export function enhance | undefined, Failure extends Record | undefined>(form_element: HTMLFormElement, submit?: import("@sveltejs/kit").SubmitFunction): { destroy(): void; }; /** * This action updates the `form` property of the current page with the given data and updates `page.status`. * In case of an error, it redirects to the nearest error page. * */ - export function applyAction< - Success extends Record | undefined, - Failure extends Record | undefined - >(result: import('@sveltejs/kit').ActionResult): Promise; + export function applyAction | undefined, Failure extends Record | undefined>(result: import("@sveltejs/kit").ActionResult): Promise; export {}; } @@ -2601,9 +2548,7 @@ declare module '$app/navigation' { * * `afterNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function afterNavigate( - callback: (navigation: import('@sveltejs/kit').AfterNavigate) => void - ): void; + export function afterNavigate(callback: (navigation: import("@sveltejs/kit").AfterNavigate) => void): void; /** * A navigation interceptor that triggers before we navigate to a URL, whether by clicking a link, calling `goto(...)`, or using the browser back/forward controls. * @@ -2615,9 +2560,7 @@ declare module '$app/navigation' { * * `beforeNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function beforeNavigate( - callback: (navigation: import('@sveltejs/kit').BeforeNavigate) => void - ): void; + export function beforeNavigate(callback: (navigation: import("@sveltejs/kit").BeforeNavigate) => void): void; /** * A lifecycle function that runs the supplied `callback` immediately before we navigate to a new URL except during full-page navigations. * @@ -2627,9 +2570,7 @@ declare module '$app/navigation' { * * `onNavigate` must be called during a component initialization. It remains active as long as the component is mounted. * */ - export function onNavigate( - callback: (navigation: import('@sveltejs/kit').OnNavigate) => MaybePromise<(() => void) | void> - ): void; + export function onNavigate(callback: (navigation: import("@sveltejs/kit").OnNavigate) => MaybePromise<(() => void) | void>): void; /** * If called when the page is being updated following a navigation (in `onMount` or `afterNavigate` or an action, for example), this disables SvelteKit's built-in scroll handling. * This is generally discouraged, since it breaks user expectations. @@ -2644,17 +2585,14 @@ declare module '$app/navigation' { * @param url Where to navigate to. Note that if you've set [`config.kit.paths.base`](https://svelte.dev/docs/kit/configuration#paths) and the URL is root-relative, you need to prepend the base path if you want to navigate within the app. * @param {Object} opts Options related to the navigation * */ - export function goto( - url: string | URL, - opts?: { - replaceState?: boolean | undefined; - noScroll?: boolean | undefined; - keepFocus?: boolean | undefined; - invalidateAll?: boolean | undefined; - invalidate?: (string | URL | ((url: URL) => boolean))[] | undefined; - state?: App.PageState | undefined; - } - ): Promise; + export function goto(url: string | URL, opts?: { + replaceState?: boolean | undefined; + noScroll?: boolean | undefined; + keepFocus?: boolean | undefined; + invalidateAll?: boolean | undefined; + invalidate?: (string | URL | ((url: URL) => boolean))[] | undefined; + state?: App.PageState | undefined; + }): Promise; /** * Causes any `load` functions belonging to the currently active page to re-run if they depend on the `url` in question, via `fetch` or `depends`. Returns a `Promise` that resolves when the page is subsequently updated. * @@ -2681,9 +2619,7 @@ declare module '$app/navigation' { * Causes all currently active remote functions to refresh, and all `load` functions belonging to the currently active page to re-run (unless disabled via the option argument). * Returns a `Promise` that resolves when the page is subsequently updated. * */ - export function refreshAll({ - includeLoadFunctions - }?: { + export function refreshAll({ includeLoadFunctions }?: { includeLoadFunctions?: boolean; }): Promise; /** @@ -2697,17 +2633,14 @@ declare module '$app/navigation' { * * @param href Page to preload * */ - export function preloadData(href: string): Promise< - | { - type: 'loaded'; - status: number; - data: Record; - } - | { - type: 'redirect'; - location: string; - } - >; + export function preloadData(href: string): Promise<{ + type: "loaded"; + status: number; + data: Record; + } | { + type: "redirect"; + location: string; + }>; /** * Programmatically imports the code for routes that haven't yet been fetched. * Typically, you might call this to speed up subsequent navigation. @@ -2809,13 +2742,7 @@ declare module '$app/paths' { } declare module '$app/server' { - import type { - RequestEvent, - RemoteCommand, - RemoteForm, - RemotePrerenderFunction, - RemoteQueryFunction - } from '@sveltejs/kit'; + import type { RequestEvent, RemoteCommand, RemoteForm, RemotePrerenderFunction, RemoteQueryFunction } from '@sveltejs/kit'; import type { StandardSchemaV1 } from '@standard-schema/spec'; /** * Read the contents of an imported asset from the filesystem @@ -2853,10 +2780,7 @@ declare module '$app/server' { * * @since 2.27 */ - export function command( - validate: 'unchecked', - fn: (arg: Input) => Output - ): RemoteCommand; + export function command(validate: "unchecked", fn: (arg: Input) => Output): RemoteCommand; /** * Creates a remote command. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2864,10 +2788,7 @@ declare module '$app/server' { * * @since 2.27 */ - export function command( - validate: Schema, - fn: (arg: StandardSchemaV1.InferOutput) => Output - ): RemoteCommand, Output>; + export function command(validate: Schema, fn: (arg: StandardSchemaV1.InferOutput) => Output): RemoteCommand, Output>; /** * Creates a form object that can be spread onto a `` element. * @@ -2883,15 +2804,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender( - fn: () => MaybePromise, - options?: - | { - inputs?: RemotePrerenderInputsGenerator; - dynamic?: boolean; - } - | undefined - ): RemotePrerenderFunction; + export function prerender(fn: () => MaybePromise, options?: { + inputs?: RemotePrerenderInputsGenerator; + dynamic?: boolean; + } | undefined): RemotePrerenderFunction; /** * Creates a remote prerender function. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2899,16 +2815,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender( - validate: 'unchecked', - fn: (arg: Input) => MaybePromise, - options?: - | { - inputs?: RemotePrerenderInputsGenerator; - dynamic?: boolean; - } - | undefined - ): RemotePrerenderFunction; + export function prerender(validate: "unchecked", fn: (arg: Input) => MaybePromise, options?: { + inputs?: RemotePrerenderInputsGenerator; + dynamic?: boolean; + } | undefined): RemotePrerenderFunction; /** * Creates a remote prerender function. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2916,16 +2826,10 @@ declare module '$app/server' { * * @since 2.27 */ - export function prerender( - schema: Schema, - fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise, - options?: - | { - inputs?: RemotePrerenderInputsGenerator>; - dynamic?: boolean; - } - | undefined - ): RemotePrerenderFunction, Output>; + export function prerender(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise, options?: { + inputs?: RemotePrerenderInputsGenerator>; + dynamic?: boolean; + } | undefined): RemotePrerenderFunction, Output>; /** * Creates a remote query. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2941,10 +2845,7 @@ declare module '$app/server' { * * @since 2.27 */ - export function query( - validate: 'unchecked', - fn: (arg: Input) => MaybePromise - ): RemoteQueryFunction; + export function query(validate: "unchecked", fn: (arg: Input) => MaybePromise): RemoteQueryFunction; /** * Creates a remote query. When called from the browser, the function will be invoked on the server via a `fetch` call. * @@ -2952,10 +2853,7 @@ declare module '$app/server' { * * @since 2.27 */ - export function query( - schema: Schema, - fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise - ): RemoteQueryFunction, Output>; + export function query(schema: Schema, fn: (arg: StandardSchemaV1.InferOutput) => MaybePromise): RemoteQueryFunction, Output>; type RemotePrerenderInputsGenerator = () => MaybePromise; type MaybePromise = T | Promise; @@ -2999,21 +2897,19 @@ declare module '$app/state' { * On the server, values can only be read during rendering (in other words _not_ in e.g. `load` functions). In the browser, the values can be read at any time. * * */ - export const page: import('@sveltejs/kit').Page; + export const page: import("@sveltejs/kit").Page; /** * A read-only object representing an in-progress navigation, with `from`, `to`, `type` and (if `type === 'popstate'`) `delta` properties. * Values are `null` when no navigation is occurring, or during server rendering. * */ - export const navigating: - | import('@sveltejs/kit').Navigation - | { - from: null; - to: null; - type: null; - willUnload: null; - delta: null; - complete: null; - }; + export const navigating: import("@sveltejs/kit").Navigation | { + from: null; + to: null; + type: null; + willUnload: null; + delta: null; + complete: null; + }; /** * A read-only reactive value that's initially `false`. If [`version.pollInterval`](https://svelte.dev/docs/kit/configuration#version) is a non-zero value, SvelteKit will poll for new versions of the app and update `current` to `true` when it detects one. `updated.check()` will force an immediate check, regardless of polling. * */ @@ -3027,10 +2923,11 @@ declare module '$app/state' { declare module '$app/stores' { export function getStores(): { + page: typeof page; - + navigating: typeof navigating; - + updated: typeof updated; }; /** @@ -3040,7 +2937,7 @@ declare module '$app/stores' { * * @deprecated Use `page` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const page: import('svelte/store').Readable; + export const page: import("svelte/store").Readable; /** * A readable store. * When navigating starts, its value is a `Navigation` object with `from`, `to`, `type` and (if `type === 'popstate'`) `delta` properties. @@ -3050,9 +2947,7 @@ declare module '$app/stores' { * * @deprecated Use `navigating` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const navigating: import('svelte/store').Readable< - import('@sveltejs/kit').Navigation | null - >; + export const navigating: import("svelte/store").Readable; /** * A readable store whose initial value is `false`. If [`version.pollInterval`](https://svelte.dev/docs/kit/configuration#version) is a non-zero value, SvelteKit will poll for new versions of the app and update the store value to `true` when it detects one. `updated.check()` will force an immediate check, regardless of polling. * @@ -3060,12 +2955,12 @@ declare module '$app/stores' { * * @deprecated Use `updated` from `$app/state` instead (requires Svelte 5, [see docs for more info](https://svelte.dev/docs/kit/migrating-to-sveltekit-2#SvelteKit-2.12:-$app-stores-deprecated)) * */ - export const updated: import('svelte/store').Readable & { + export const updated: import("svelte/store").Readable & { check(): Promise; }; export {}; -} /** +}/** * It's possible to tell SvelteKit how to type objects inside your app by declaring the `App` namespace. By default, a new project will have a file called `src/app.d.ts` containing the following: * * ```ts @@ -3147,4 +3042,4 @@ declare module '$service-worker' { export const version: string; } -//# sourceMappingURL=index.d.ts.map +//# sourceMappingURL=index.d.ts.map \ No newline at end of file From 0a1834b6e6a09129e5038ce22a962496e78d729c Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 14 Aug 2025 11:37:18 -0600 Subject: [PATCH 68/74] hopefully I oneshot this with my brain --- .changeset/whole-bananas-sort.md | 2 +- packages/adapter-auto/index.js | 4 +- packages/adapter-cloudflare/index.js | 8 ++-- packages/adapter-netlify/index.js | 26 ++++++------ ...ng.server.js => instrumentation.server.js} | 0 .../test/apps/basic/svelte.config.js | 2 +- packages/adapter-node/index.js | 12 +++--- packages/adapter-vercel/index.js | 24 +++++------ packages/kit/src/core/adapt/builder.js | 33 ++++++++------- packages/kit/src/core/config/index.spec.js | 3 +- packages/kit/src/core/config/options.js | 6 ++- packages/kit/src/exports/public.d.ts | 40 ++++++++++--------- packages/kit/src/exports/vite/dev/index.js | 8 ++-- packages/kit/src/exports/vite/index.js | 24 ++++++----- packages/kit/src/exports/vite/utils.js | 6 +-- packages/kit/src/exports/vite/utils.spec.js | 12 ++++-- packages/kit/src/runtime/telemetry/otel.js | 2 +- .../runtime/telemetry/otel.missing.spec.js | 2 +- packages/kit/src/types/global-private.d.ts | 2 +- .../kit/test/apps/basics/src/hooks.server.js | 1 - ...ng-config.js => instrumentation.server.js} | 2 +- .../kit/test/apps/basics/svelte.config.js | 3 ++ packages/kit/types/index.d.ts | 40 ++++++++++--------- 23 files changed, 142 insertions(+), 120 deletions(-) rename packages/adapter-netlify/test/apps/basic/src/{tracing.server.js => instrumentation.server.js} (100%) rename packages/kit/test/apps/basics/src/{lib/tracing-config.js => instrumentation.server.js} (96%) diff --git a/.changeset/whole-bananas-sort.md b/.changeset/whole-bananas-sort.md index e3aca360ce43..3fc971d0ffa8 100644 --- a/.changeset/whole-bananas-sort.md +++ b/.changeset/whole-bananas-sort.md @@ -6,4 +6,4 @@ '@sveltejs/kit': minor --- -feat: add `tracing.server.ts` for tracing instrumentation and setup +feat: add `instrumentation.server.ts` for tracing and observability setup diff --git a/packages/adapter-auto/index.js b/packages/adapter-auto/index.js index 578c8115c02d..0bc8faae5c6b 100644 --- a/packages/adapter-auto/index.js +++ b/packages/adapter-auto/index.js @@ -153,8 +153,8 @@ export default () => ({ 'The read function imported from $app/server only works in certain environments' ); }, - tracing: () => { - supports_error('`tracing.server.js` only works in certain environments'); + instrumentation: () => { + supports_error('`instrumentation.server.js` only works in certain environments'); } } }); diff --git a/packages/adapter-cloudflare/index.js b/packages/adapter-cloudflare/index.js index d7e5682226b4..999c05c1275e 100644 --- a/packages/adapter-cloudflare/index.js +++ b/packages/adapter-cloudflare/index.js @@ -113,10 +113,10 @@ export default function (options = {}) { ASSETS: assets_binding } }); - if (builder.hasServerTracingFile()) { - builder.trace({ + if (builder.hasServerInstrumentationFile()) { + builder.instrument({ entrypoint: worker_dest, - tracing: `${builder.getServerDirectory()}/tracing.server.js` + instrumentation: `${builder.getServerDirectory()}/instrumentation.server.js` }); } @@ -191,7 +191,7 @@ export default function (options = {}) { return true; }, - tracing: () => true + instrumentation: () => true } }; } diff --git a/packages/adapter-netlify/index.js b/packages/adapter-netlify/index.js index 1ff8ee41dfcb..0f8b75f5ccdb 100644 --- a/packages/adapter-netlify/index.js +++ b/packages/adapter-netlify/index.js @@ -108,7 +108,7 @@ export default function ({ split = false, edge = edge_set_in_env_var } = {}) { return true; }, - tracing: () => true + instrumentation: () => true } }; } @@ -202,18 +202,18 @@ async function generate_edge_functions({ builder }) { outfile: '.netlify/edge-functions/render.js', ...esbuild_config }), - builder.hasServerTracingFile() && + builder.hasServerInstrumentationFile() && esbuild.build({ - entryPoints: [`${builder.getServerDirectory()}/tracing.server.js`], - outfile: '.netlify/edge/tracing.server.js', + entryPoints: [`${builder.getServerDirectory()}/instrumentation.server.js`], + outfile: '.netlify/edge/instrumentation.server.js', ...esbuild_config }) ]); - if (builder.hasServerTracingFile()) { - builder.trace({ + if (builder.hasServerInstrumentationFile()) { + builder.instrument({ entrypoint: '.netlify/edge-functions/render.js', - tracing: '.netlify/edge/tracing.server.js', + instrumentation: '.netlify/edge/instrumentation.server.js', start: '.netlify/edge/start.js' }); } @@ -294,10 +294,10 @@ function generate_lambda_functions({ builder, publish, split }) { writeFileSync(`.netlify/functions-internal/${name}.mjs`, fn); writeFileSync(`.netlify/functions-internal/${name}.json`, fn_config); - if (builder.hasServerTracingFile()) { - builder.trace({ + if (builder.hasServerInstrumentationFile()) { + builder.instrument({ entrypoint: `.netlify/functions-internal/${name}.mjs`, - tracing: '.netlify/server/tracing.server.js', + instrumentation: '.netlify/server/instrumentation.server.js', start: `.netlify/functions-start/${name}.start.mjs`, module: { exports: ['handler'] @@ -318,10 +318,10 @@ function generate_lambda_functions({ builder, publish, split }) { writeFileSync(`.netlify/functions-internal/${FUNCTION_PREFIX}render.json`, fn_config); writeFileSync(`.netlify/functions-internal/${FUNCTION_PREFIX}render.mjs`, fn); - if (builder.hasServerTracingFile()) { - builder.trace({ + if (builder.hasServerInstrumentationFile()) { + builder.instrument({ entrypoint: `.netlify/functions-internal/${FUNCTION_PREFIX}render.mjs`, - tracing: '.netlify/server/tracing.server.js', + instrumentation: '.netlify/server/instrumentation.server.js', start: `.netlify/functions-start/${FUNCTION_PREFIX}render.start.mjs`, module: { exports: ['handler'] diff --git a/packages/adapter-netlify/test/apps/basic/src/tracing.server.js b/packages/adapter-netlify/test/apps/basic/src/instrumentation.server.js similarity index 100% rename from packages/adapter-netlify/test/apps/basic/src/tracing.server.js rename to packages/adapter-netlify/test/apps/basic/src/instrumentation.server.js diff --git a/packages/adapter-netlify/test/apps/basic/svelte.config.js b/packages/adapter-netlify/test/apps/basic/svelte.config.js index fe7386b1bf63..a478bdf4f516 100644 --- a/packages/adapter-netlify/test/apps/basic/svelte.config.js +++ b/packages/adapter-netlify/test/apps/basic/svelte.config.js @@ -5,7 +5,7 @@ const config = { kit: { adapter: adapter(), experimental: { - tracing: { + instrumentation: { serverFile: true } } diff --git a/packages/adapter-node/index.js b/packages/adapter-node/index.js index 024c402883c4..e17408dfaec1 100644 --- a/packages/adapter-node/index.js +++ b/packages/adapter-node/index.js @@ -54,8 +54,8 @@ export default function (opts = {}) { manifest: `${tmp}/manifest.js` }; - if (builder.hasServerTracingFile()) { - input['tracing.server'] = `${tmp}/tracing.server.js`; + if (builder.hasServerInstrumentationFile()) { + input['instrumentation.server'] = `${tmp}/instrumentation.server.js`; } // we bundle the Vite output so that deployments only need @@ -97,10 +97,10 @@ export default function (opts = {}) { } }); - if (builder.hasServerTracingFile()) { - builder.trace({ + if (builder.hasServerInstrumentationFile()) { + builder.instrument({ entrypoint: `${out}/index.js`, - tracing: `${out}/server/tracing.server.js`, + instrumentation: `${out}/server/instrumentation.server.js`, module: { exports: ['path', 'host', 'port', 'server'] } @@ -110,7 +110,7 @@ export default function (opts = {}) { supports: { read: () => true, - tracing: () => true + instrumentation: () => true } }; } diff --git a/packages/adapter-vercel/index.js b/packages/adapter-vercel/index.js index 3062952a9ab4..58f11ead9d20 100644 --- a/packages/adapter-vercel/index.js +++ b/packages/adapter-vercel/index.js @@ -100,10 +100,10 @@ const plugin = function (defaults = {}) { MANIFEST: './manifest.js' } }); - if (builder.hasServerTracingFile()) { - builder.trace({ + if (builder.hasServerInstrumentationFile()) { + builder.instrument({ entrypoint: `${tmp}/index.js`, - tracing: `${builder.getServerDirectory()}/tracing.server.js` + instrumentation: `${builder.getServerDirectory()}/instrumentation.server.js` }); } @@ -182,16 +182,16 @@ const plugin = function (defaults = {}) { }); let instrumentation_result; - if (builder.hasServerTracingFile()) { + if (builder.hasServerInstrumentationFile()) { instrumentation_result = await esbuild.build({ - entryPoints: [`${builder.getServerDirectory()}/tracing.server.js`], - outfile: `${outdir}/tracing.server.js`, + entryPoints: [`${builder.getServerDirectory()}/instrumentation.server.js`], + outfile: `${outdir}/instrumentation.server.js`, ...esbuild_config }); - builder.trace({ + builder.instrument({ entrypoint: `${outdir}/index.js`, - tracing: `${outdir}/tracing.server.js`, + instrumentation: `${outdir}/instrumentation.server.js`, module: { generateText: generate_traced_edge_module } @@ -510,7 +510,7 @@ const plugin = function (defaults = {}) { return true; }, - tracing: () => true + instrumentation: () => true } }; }; @@ -838,11 +838,11 @@ function is_prerendered(route) { } /** - * @param {{ tracing: string; start: string }} opts + * @param {{ instrumentation: string; start: string }} opts */ -function generate_traced_edge_module({ tracing, start }) { +function generate_traced_edge_module({ instrumentation, start }) { return `\ -import './${tracing}'; +import './${instrumentation}'; const promise = import('./${start}'); /** diff --git a/packages/kit/src/core/adapt/builder.js b/packages/kit/src/core/adapt/builder.js index a73581699d21..3d0de4472e73 100644 --- a/packages/kit/src/core/adapt/builder.js +++ b/packages/kit/src/core/adapt/builder.js @@ -236,21 +236,21 @@ export function create_builder({ return copy(`${config.kit.outDir}/output/server`, dest); }, - hasServerTracingFile() { - return existsSync(`${config.kit.outDir}/output/server/tracing.server.js`); + hasServerInstrumentationFile() { + return existsSync(`${config.kit.outDir}/output/server/instrumentation.server.js`); }, - trace({ + instrument({ entrypoint, - tracing, + instrumentation, start = join(dirname(entrypoint), 'start.js'), module = { exports: ['default'] } }) { - if (!existsSync(tracing)) { + if (!existsSync(instrumentation)) { throw new Error( - `Tracing file ${tracing} not found. This is probably a bug in your adapter.` + `Instrumentation file ${instrumentation} not found. This is probably a bug in your adapter.` ); } if (!existsSync(entrypoint)) { @@ -264,14 +264,17 @@ export function create_builder({ copy(`${entrypoint}.map`, `${start}.map`); } - const relative_tracing = relative(dirname(entrypoint), tracing); + const relative_instrumentation = relative(dirname(entrypoint), instrumentation); const relative_start = relative(dirname(entrypoint), start); const facade = 'generateText' in module - ? module.generateText({ tracing: relative_tracing, start: relative_start }) - : create_tracing_facade({ - tracing: relative_tracing, + ? module.generateText({ + instrumentation: relative_instrumentation, + start: relative_start + }) + : create_instrumentation_facade({ + instrumentation: relative_instrumentation, start: relative_start, exports: module.exports }); @@ -306,17 +309,17 @@ async function compress_file(file, format = 'gz') { /** * Given a list of exports, generate a facade that: - * - Imports the tracing file + * - Imports the instrumentation file * - Imports `exports` from the entrypoint (dynamically, if `tla` is true) * - Re-exports `exports` from the entrypoint * * `default` receives special treatment: It will be imported as `default` and exported with `export default`. * - * @param {{ tracing: string; start: string; exports: string[] }} opts + * @param {{ instrumentation: string; start: string; exports: string[] }} opts * @returns {string} */ -function create_tracing_facade({ tracing, start, exports }) { - const import_tracing = `import './${tracing}';`; +function create_instrumentation_facade({ instrumentation, start, exports }) { + const import_instrumentation = `import './${instrumentation}';`; let alias_index = 0; const aliases = new Map(); @@ -358,5 +361,5 @@ function create_tracing_facade({ tracing, start, exports }) { .filter(Boolean) .join('\n'); - return `${import_tracing}\n${entrypoint_facade}`; + return `${import_instrumentation}\n${entrypoint_facade}`; } diff --git a/packages/kit/src/core/config/index.spec.js b/packages/kit/src/core/config/index.spec.js index b6f0f16931d4..3c557a28a13b 100644 --- a/packages/kit/src/core/config/index.spec.js +++ b/packages/kit/src/core/config/index.spec.js @@ -77,7 +77,8 @@ const get_defaults = (prefix = '') => ({ privatePrefix: '' }, experimental: { - tracing: { server: false, serverFile: false }, + tracing: { server: false }, + instrumentation: { server: false }, remoteFunctions: false }, files: { diff --git a/packages/kit/src/core/config/options.js b/packages/kit/src/core/config/options.js index e40e1638016d..dbf7cf482007 100644 --- a/packages/kit/src/core/config/options.js +++ b/packages/kit/src/core/config/options.js @@ -121,8 +121,10 @@ const options = object( experimental: object({ tracing: object({ - server: boolean(false), - serverFile: boolean(false) + server: boolean(false) + }), + instrumentation: object({ + server: boolean(false) }), remoteFunctions: boolean(false) }), diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index 1ed2fc3f4be2..d936e074e7f1 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -53,11 +53,10 @@ export interface Adapter { read?: (details: { config: any; route: { id: string } }) => boolean; /** - * Test support for `tracing`. To pass, the adapter must support `tracing.server.js` and - * also deploy to a platform that supports `@opentelemetry/api`. + * Test support for `instrumentation.server.js`. To pass, the adapter must support running `instrumentation.server.js` prior to the application code. * @since 2.31.0 */ - tracing?: () => boolean; + instrumentation?: () => boolean; }; /** * Creates an `Emulator`, which allows the adapter to influence the environment @@ -196,43 +195,43 @@ export interface Builder { ) => string[]; /** - * Check if the server tracing file exists. - * @returns true if the server tracing file exists, false otherwise + * Check if the server instrumentation file exists. + * @returns true if the server instrumentation file exists, false otherwise * @since 2.31.0 */ - hasServerTracingFile: () => boolean; + hasServerInstrumentationFile: () => boolean; /** - * Trace `entrypoint` with `tracing`. + * Instrument `entrypoint` with `instrumentation`. * * Renames `entrypoint` to `start` and creates a new module at - * `entrypoint` which imports `tracing` and then dynamically imports `start`. This allows - * the module hooks necessary for tracing libraries to be loaded prior to any application code. + * `entrypoint` which imports `instrumentation` and then dynamically imports `start`. This allows + * the module hooks necessary for instrumentation libraries to be loaded prior to any application code. * * Caveats: * - "Live exports" will not work. If your adapter uses live exports, your users will need to manually import the server instrumentation on startup. * - If `tla` is `false`, OTEL auto-instrumentation may not work properly. Use it if your environment supports it. - * - Use `hasServerTracingFile` to check if the user has a server tracing file; if they don't, you shouldn't do this. + * - Use `hasServerInstrumentationFile` to check if the user has a server instrumentation file; if they don't, you shouldn't do this. * * @param options an object containing the following properties: * @param options.entrypoint the path to the entrypoint to trace. - * @param options.tracing the path to the tracing file. + * @param options.instrumentation the path to the instrumentation file. * @param options.start the name of the start file. This is what `entrypoint` will be renamed to. * @param options.module configuration for the resulting entrypoint module. * @param options.module.exports - * @param options.module.generateText a function that receives the relative paths to the tracing and start files, and generates the text of the module to be traced. If not provided, the default implementation will be used, which uses top-level await. + * @param options.module.generateText a function that receives the relative paths to the instrumentation and start files, and generates the text of the module to be traced. If not provided, the default implementation will be used, which uses top-level await. * @since 2.31.0 */ - trace: (args: { + instrument: (args: { entrypoint: string; - tracing: string; + instrumentation: string; start?: string; module?: | { exports: string[]; } | { - generateText: (args: { tracing: string; start: string }) => string; + generateText: (args: { instrumentation: string; start: string }) => string; }; }) => void; @@ -460,7 +459,7 @@ export interface KitConfig { /** Experimental features. Here be dragons. These are not subject to semantic versioning, so breaking changes or removal can happen in any release. */ experimental?: { /** - * Options to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). + * Options for enabling server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). * @default { server: false, serverFile: false } * @since 2.31.0 */ @@ -471,13 +470,18 @@ export interface KitConfig { * @since 2.31.0 */ server?: boolean; + }; + /** + * @since 2.31.0 + */ + instrumentation?: { /** - * Enables `tracing.server.js` for tracing instrumentation. + * Enables `instrumentation.server.js` for tracing instrumentation. * @default false * @since 2.31.0 */ - serverFile?: boolean; + server?: boolean; }; /** diff --git a/packages/kit/src/exports/vite/dev/index.js b/packages/kit/src/exports/vite/dev/index.js index e4277ee03d6e..e7a27a72e5bb 100644 --- a/packages/kit/src/exports/vite/dev/index.js +++ b/packages/kit/src/exports/vite/dev/index.js @@ -501,12 +501,12 @@ export async function dev(vite, vite_config, svelte_config) { return; } - const resolved_tracing = resolve_entry( - path.join(svelte_config.kit.files.src, 'tracing.server') + const resolved_instrumentation = resolve_entry( + path.join(svelte_config.kit.files.src, 'instrumentation.server') ); - if (resolved_tracing) { - await vite.ssrLoadModule(resolved_tracing); + if (resolved_instrumentation) { + await vite.ssrLoadModule(resolved_instrumentation); } // we have to import `Server` before calling `set_assets` diff --git a/packages/kit/src/exports/vite/index.js b/packages/kit/src/exports/vite/index.js index 5805741a16e4..bbaf6686a63a 100644 --- a/packages/kit/src/exports/vite/index.js +++ b/packages/kit/src/exports/vite/index.js @@ -339,7 +339,7 @@ async function kit({ svelte_config }) { __SVELTEKIT_EMBEDDED__: s(kit.embedded), __SVELTEKIT_EXPERIMENTAL__REMOTE_FUNCTIONS__: s(kit.experimental.remoteFunctions), __SVELTEKIT_CLIENT_ROUTING__: s(kit.router.resolution === 'client'), - __SVELTEKIT_SERVER_TRACING_ENABLED__: s(kit.experimental.tracing.server), + __SVELTEKIT_SERVER_TRACING_ENABLED__: s(kit.experimental.instrumentation.server), __SVELTEKIT_PAYLOAD__: new_config.build.ssr ? '{}' : `globalThis.__sveltekit_${version_hash}` @@ -355,7 +355,7 @@ async function kit({ svelte_config }) { __SVELTEKIT_EMBEDDED__: s(kit.embedded), __SVELTEKIT_EXPERIMENTAL__REMOTE_FUNCTIONS__: s(kit.experimental.remoteFunctions), __SVELTEKIT_CLIENT_ROUTING__: s(kit.router.resolution === 'client'), - __SVELTEKIT_SERVER_TRACING_ENABLED__: s(kit.experimental.tracing.server), + __SVELTEKIT_SERVER_TRACING_ENABLED__: s(kit.experimental.instrumentation.server), __SVELTEKIT_PAYLOAD__: 'globalThis.__sveltekit_dev' }; @@ -783,21 +783,23 @@ async function kit({ svelte_config }) { input[name] = path.resolve(file); }); - // ...and the server tracing file - const server_tracing = resolve_entry(path.join(kit.files.src, 'tracing.server')); - if (server_tracing) { + // ...and the server instrumentation file + const server_instrumentation = resolve_entry( + path.join(kit.files.src, 'instrumentation.server') + ); + if (server_instrumentation) { const { adapter } = kit; - if (adapter && !adapter.supports?.tracing?.()) { - throw new Error(`${server_tracing} is unsupported in ${adapter.name}.`); + if (adapter && !adapter.supports?.instrumentation?.()) { + throw new Error(`${server_instrumentation} is unsupported in ${adapter.name}.`); } - if (!kit.experimental.tracing.serverFile) { + if (!kit.experimental.instrumentation.server) { error_for_missing_config( - 'tracing.server.js', - 'kit.experimental.tracing.serverFile', + 'instrumentation.server.js', + 'kit.experimental.instrumentation.server', 'true' ); } - input['tracing.server'] = server_tracing; + input['instrumentation.server'] = server_instrumentation; } // ...and every .remote file diff --git a/packages/kit/src/exports/vite/utils.js b/packages/kit/src/exports/vite/utils.js index e2017a53d68e..3eb71b0e0852 100644 --- a/packages/kit/src/exports/vite/utils.js +++ b/packages/kit/src/exports/vite/utils.js @@ -175,16 +175,16 @@ export function stackless(message) { export const strip_virtual_prefix = /** @param {string} id */ (id) => id.replace('\0virtual:', ''); /** - * For `error_for_missing_config('tracing.server.js', 'kit.experimental.tracing.serverFile', true)`, + * For `error_for_missing_config('instrumentation.server.js', 'kit.experimental.instrumentation.server', true)`, * returns: * * ``` - * To enable `tracing.server.js`, add the following to your `svelte.config.js`: + * To enable `instrumentation.server.js`, add the following to your `svelte.config.js`: * *\`\`\`js * kit: * experimental: - * tracing: + * instrumentation: * server: true * } * } diff --git a/packages/kit/src/exports/vite/utils.spec.js b/packages/kit/src/exports/vite/utils.spec.js index f329c3154ee8..bf13485390ad 100644 --- a/packages/kit/src/exports/vite/utils.spec.js +++ b/packages/kit/src/exports/vite/utils.spec.js @@ -55,16 +55,20 @@ test('error_for_missing_config - simple single level config', () => { test('error_for_missing_config - nested config', () => { expect(() => - error_for_missing_config('tracing.server.js', 'kit.experimental.tracing.serverFile', 'true') + error_for_missing_config( + 'instrumentation.server.js', + 'kit.experimental.instrumentation.server', + 'true' + ) ).toThrow( dedent` - To enable \`tracing.server.js\`, add the following to your \`svelte.config.js\`: + To enable \`instrumentation.server.js\`, add the following to your \`svelte.config.js\`: \`\`\`js kit: { experimental: { - tracing: { - serverFile: true + instrumentation: { + server: true } } } diff --git a/packages/kit/src/runtime/telemetry/otel.js b/packages/kit/src/runtime/telemetry/otel.js index 5ef6a71ac3e5..4a4c40dda492 100644 --- a/packages/kit/src/runtime/telemetry/otel.js +++ b/packages/kit/src/runtime/telemetry/otel.js @@ -15,7 +15,7 @@ if (__SVELTEKIT_SERVER_TRACING_ENABLED__) { }) .catch(() => { throw new Error( - 'Tracing is enabled (see `config.kit.experimental.tracing.server` in your svelte.config.js), but `@opentelemetry/api` is not available. Have you installed it?' + 'Tracing is enabled (see `config.kit.experimental.instrumentation.server` in your svelte.config.js), but `@opentelemetry/api` is not available. Have you installed it?' ); }); } diff --git a/packages/kit/src/runtime/telemetry/otel.missing.spec.js b/packages/kit/src/runtime/telemetry/otel.missing.spec.js index 256e9c3f1d9a..fb4285aa5ea1 100644 --- a/packages/kit/src/runtime/telemetry/otel.missing.spec.js +++ b/packages/kit/src/runtime/telemetry/otel.missing.spec.js @@ -11,6 +11,6 @@ vi.mock('@opentelemetry/api', () => { test('otel should throw an error when tracing is enabled but @opentelemetry/api is not available', async () => { const { otel } = await import('./otel.js'); await expect(otel).rejects.toThrow( - 'Tracing is enabled (see `config.kit.experimental.tracing.server` in your svelte.config.js), but `@opentelemetry/api` is not available. Have you installed it?' + 'Tracing is enabled (see `config.kit.experimental.instrumentation.server` in your svelte.config.js), but `@opentelemetry/api` is not available. Have you installed it?' ); }); diff --git a/packages/kit/src/types/global-private.d.ts b/packages/kit/src/types/global-private.d.ts index 373eccfd89fe..9972a2d8bd51 100644 --- a/packages/kit/src/types/global-private.d.ts +++ b/packages/kit/src/types/global-private.d.ts @@ -4,7 +4,7 @@ declare global { const __SVELTEKIT_APP_VERSION_POLL_INTERVAL__: number; const __SVELTEKIT_DEV__: boolean; const __SVELTEKIT_EMBEDDED__: boolean; - /** True if `config.kit.experimental.tracing.server` is `true` */ + /** True if `config.kit.experimental.instrumentation.server` is `true` */ const __SVELTEKIT_SERVER_TRACING_ENABLED__: boolean; /** true if corresponding config option is set to true */ const __SVELTEKIT_EXPERIMENTAL__REMOTE_FUNCTIONS__: boolean; diff --git a/packages/kit/test/apps/basics/src/hooks.server.js b/packages/kit/test/apps/basics/src/hooks.server.js index e6ec0e695964..de38b0ecd486 100644 --- a/packages/kit/test/apps/basics/src/hooks.server.js +++ b/packages/kit/test/apps/basics/src/hooks.server.js @@ -5,7 +5,6 @@ import fs from 'node:fs'; import { COOKIE_NAME } from './routes/cookies/shared'; import { _set_from_init } from './routes/init-hooks/+page.server'; import { getRequestEvent } from '$app/server'; -import '$lib/tracing-config'; // @ts-ignore this doesn't exist in old Node Promise.withResolvers ??= () => { diff --git a/packages/kit/test/apps/basics/src/lib/tracing-config.js b/packages/kit/test/apps/basics/src/instrumentation.server.js similarity index 96% rename from packages/kit/test/apps/basics/src/lib/tracing-config.js rename to packages/kit/test/apps/basics/src/instrumentation.server.js index b944279edecc..aa4ad0d2f781 100644 --- a/packages/kit/test/apps/basics/src/lib/tracing-config.js +++ b/packages/kit/test/apps/basics/src/instrumentation.server.js @@ -1,5 +1,5 @@ /** @import {SpanExporter} from '@opentelemetry/sdk-trace-node' */ -/** @import {SpanData} from '../../../../types' */ +/** @import {SpanData} from '../../../types' */ import { NodeSDK } from '@opentelemetry/sdk-node'; import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-node'; import fs from 'node:fs'; diff --git a/packages/kit/test/apps/basics/svelte.config.js b/packages/kit/test/apps/basics/svelte.config.js index f5861fcefdbd..518bf476d586 100644 --- a/packages/kit/test/apps/basics/svelte.config.js +++ b/packages/kit/test/apps/basics/svelte.config.js @@ -22,6 +22,9 @@ const config = { remoteFunctions: true, tracing: { server: true + }, + instrumentation: { + server: true } }, diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index 77f3404da131..e11cd89a7f8e 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -30,11 +30,10 @@ declare module '@sveltejs/kit' { read?: (details: { config: any; route: { id: string } }) => boolean; /** - * Test support for `tracing`. To pass, the adapter must support `tracing.server.js` and - * also deploy to a platform that supports `@opentelemetry/api`. + * Test support for `instrumentation.server.js`. To pass, the adapter must support running `instrumentation.server.js` prior to the application code. * @since 2.31.0 */ - tracing?: () => boolean; + instrumentation?: () => boolean; }; /** * Creates an `Emulator`, which allows the adapter to influence the environment @@ -173,42 +172,42 @@ declare module '@sveltejs/kit' { ) => string[]; /** - * Check if the server tracing file exists. - * @returns true if the server tracing file exists, false otherwise + * Check if the server instrumentation file exists. + * @returns true if the server instrumentation file exists, false otherwise * @since 2.31.0 */ - hasServerTracingFile: () => boolean; + hasServerInstrumentationFile: () => boolean; /** - * Trace `entrypoint` with `tracing`. + * Instrument `entrypoint` with `instrumentation`. * * Renames `entrypoint` to `start` and creates a new module at - * `entrypoint` which imports `tracing` and then dynamically imports `start`. This allows - * the module hooks necessary for tracing libraries to be loaded prior to any application code. + * `entrypoint` which imports `instrumentation` and then dynamically imports `start`. This allows + * the module hooks necessary for instrumentation libraries to be loaded prior to any application code. * * Caveats: * - "Live exports" will not work. If your adapter uses live exports, your users will need to manually import the server instrumentation on startup. * - If `tla` is `false`, OTEL auto-instrumentation may not work properly. Use it if your environment supports it. - * - Use `hasServerTracingFile` to check if the user has a server tracing file; if they don't, you shouldn't do this. + * - Use `hasServerInstrumentationFile` to check if the user has a server instrumentation file; if they don't, you shouldn't do this. * * @param options an object containing the following properties: * @param options.entrypoint the path to the entrypoint to trace. - * @param options.tracing the path to the tracing file. + * @param options.instrumentation the path to the instrumentation file. * @param options.start the name of the start file. This is what `entrypoint` will be renamed to. * @param options.module configuration for the resulting entrypoint module. - * @param options.module.generateText a function that receives the relative paths to the tracing and start files, and generates the text of the module to be traced. If not provided, the default implementation will be used, which uses top-level await. + * @param options.module.generateText a function that receives the relative paths to the instrumentation and start files, and generates the text of the module to be traced. If not provided, the default implementation will be used, which uses top-level await. * @since 2.31.0 */ - trace: (args: { + instrument: (args: { entrypoint: string; - tracing: string; + instrumentation: string; start?: string; module?: | { exports: string[]; } | { - generateText: (args: { tracing: string; start: string }) => string; + generateText: (args: { instrumentation: string; start: string }) => string; }; }) => void; @@ -436,7 +435,7 @@ declare module '@sveltejs/kit' { /** Experimental features. Here be dragons. These are not subject to semantic versioning, so breaking changes or removal can happen in any release. */ experimental?: { /** - * Options to enable server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). + * Options for enabling server-side [OpenTelemetry](https://opentelemetry.io/) tracing for SvelteKit operations including the [`handle` hook](https://svelte.dev/docs/kit/hooks#Server-hooks-handle), [`load` functions](https://svelte.dev/docs/kit/load), [form actions](https://svelte.dev/docs/kit/form-actions), and [remote functions](https://svelte.dev/docs/kit/remote-functions). * @default { server: false, serverFile: false } * @since 2.31.0 */ @@ -447,13 +446,18 @@ declare module '@sveltejs/kit' { * @since 2.31.0 */ server?: boolean; + }; + /** + * @since 2.31.0 + */ + instrumentation?: { /** - * Enables `tracing.server.js` for tracing instrumentation. + * Enables `instrumentation.server.js` for tracing instrumentation. * @default false * @since 2.31.0 */ - serverFile?: boolean; + server?: boolean; }; /** From bd73dc9a1b6d2e72e3c0d55f23c7fd2272477340 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 14 Aug 2025 13:40:13 -0600 Subject: [PATCH 69/74] last fixes --- .../docs/10-getting-started/30-project-structure.md | 3 ++- documentation/docs/30-advanced/68-observability.md | 12 +++++++----- packages/kit/src/exports/public.d.ts | 2 +- packages/kit/types/index.d.ts | 2 +- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/documentation/docs/10-getting-started/30-project-structure.md b/documentation/docs/10-getting-started/30-project-structure.md index 773a730f2c3b..1c947a310435 100644 --- a/documentation/docs/10-getting-started/30-project-structure.md +++ b/documentation/docs/10-getting-started/30-project-structure.md @@ -55,7 +55,8 @@ The `src` directory contains the meat of your project. Everything except `src/ro - `hooks.client.js` contains your client [hooks](hooks) - `hooks.server.js` contains your server [hooks](hooks) - `service-worker.js` contains your [service worker](service-workers) -- `tracing.server.js` contains your [tracing](observability) setup and instrumentation code +- `instrumentation.server.js` contains your [observability](observability) setup and instrumentation code + - Requires adapter support. If your adapter supports it, it is guarnteed to run prior to loading and running your application code. (Whether the project contains `.js` or `.ts` files depends on whether you opt to use TypeScript when you create your project.) diff --git a/documentation/docs/30-advanced/68-observability.md b/documentation/docs/30-advanced/68-observability.md index 24b92c444fa5..aa57ddc25e52 100644 --- a/documentation/docs/30-advanced/68-observability.md +++ b/documentation/docs/30-advanced/68-observability.md @@ -15,7 +15,7 @@ Sometimes, you may need to observe how your application is behaving in order to - [Form actions](form-actions) - [Remote functions](remote-functions) -Just telling SvelteKit to emit spans won't get you far, though — you need to actually collect them somewhere to be able to view them. SvelteKit provides `src/tracing.server.ts` as a place to write your tracing setup and instrumentation code. It's guaranteed to be run prior to your application code being imported, providing your deployment platform supports it and your adapter is aware of it. +Just telling SvelteKit to emit spans won't get you far, though — you need to actually collect them somewhere to be able to view them. SvelteKit provides `src/instrumentation.server.ts` as a place to write your tracing setup and instrumentation code. It's guaranteed to be run prior to your application code being imported, providing your deployment platform supports it and your adapter is aware of it. To enable both of these features, add the following to your `svelte.config.js`: @@ -25,15 +25,17 @@ export default { kit: { +++experimental: { tracing: { - server: true, - serverFile: true + server: true + }, + instrumentation: { + server: true } }+++ } }; ``` -> [!NOTE] Tracing — and more significantly, tracing instrumentation — can have a nontrivial overhead. Before you go all-in on tracing, consider whether or not you really need it, or if it might be more appropriate to turn it on in development and preview environments only. +> [!NOTE] Tracing — and more significantly, observability instrumentation — can have a nontrivial overhead. Before you go all-in on tracing, consider whether or not you really need it, or if it might be more appropriate to turn it on in development and preview environments only. ## Development quickstart @@ -44,7 +46,7 @@ To view your first trace, you'll need to set up a local collector. We'll use [Ja ```sh npm i @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-oltp-proto import-in-the-middle ``` -- Create `src/tracing.server.ts` with the following: +- Create `src/instrumentation.server.ts` with the following: ```ts import { NodeSDK } from '@opentelemetry/sdk-node'; diff --git a/packages/kit/src/exports/public.d.ts b/packages/kit/src/exports/public.d.ts index d936e074e7f1..bf0286ea9527 100644 --- a/packages/kit/src/exports/public.d.ts +++ b/packages/kit/src/exports/public.d.ts @@ -477,7 +477,7 @@ export interface KitConfig { */ instrumentation?: { /** - * Enables `instrumentation.server.js` for tracing instrumentation. + * Enables `instrumentation.server.js` for tracing and observability instrumentation. * @default false * @since 2.31.0 */ diff --git a/packages/kit/types/index.d.ts b/packages/kit/types/index.d.ts index e11cd89a7f8e..ccac49395701 100644 --- a/packages/kit/types/index.d.ts +++ b/packages/kit/types/index.d.ts @@ -453,7 +453,7 @@ declare module '@sveltejs/kit' { */ instrumentation?: { /** - * Enables `instrumentation.server.js` for tracing instrumentation. + * Enables `instrumentation.server.js` for tracing and observability instrumentation. * @default false * @since 2.31.0 */ From 50d942a5b7828d4d2ca48c8b5cce4c335370cb50 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 14 Aug 2025 13:49:10 -0600 Subject: [PATCH 70/74] fix --- packages/kit/test/apps/basics/svelte.config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/kit/test/apps/basics/svelte.config.js b/packages/kit/test/apps/basics/svelte.config.js index 518bf476d586..43cac801aa24 100644 --- a/packages/kit/test/apps/basics/svelte.config.js +++ b/packages/kit/test/apps/basics/svelte.config.js @@ -14,7 +14,8 @@ const config = { }; }, supports: { - read: () => true + read: () => true, + instrumentation: () => true } }, From d9ab921b401fcd959e4dece5e17deebf7a9de45f Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 14 Aug 2025 13:54:26 -0600 Subject: [PATCH 71/74] fix --- packages/adapter-netlify/test/apps/basic/svelte.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/adapter-netlify/test/apps/basic/svelte.config.js b/packages/adapter-netlify/test/apps/basic/svelte.config.js index a478bdf4f516..050579db13ba 100644 --- a/packages/adapter-netlify/test/apps/basic/svelte.config.js +++ b/packages/adapter-netlify/test/apps/basic/svelte.config.js @@ -6,7 +6,7 @@ const config = { adapter: adapter(), experimental: { instrumentation: { - serverFile: true + server: true } } } From a7b2430c47ec54d9aa6400aa7bddc694a270d6a9 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 14 Aug 2025 15:23:21 -0600 Subject: [PATCH 72/74] small docs addition --- documentation/docs/30-advanced/68-observability.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/documentation/docs/30-advanced/68-observability.md b/documentation/docs/30-advanced/68-observability.md index aa57ddc25e52..db85b4262fb8 100644 --- a/documentation/docs/30-advanced/68-observability.md +++ b/documentation/docs/30-advanced/68-observability.md @@ -37,6 +37,19 @@ export default { > [!NOTE] Tracing — and more significantly, observability instrumentation — can have a nontrivial overhead. Before you go all-in on tracing, consider whether or not you really need it, or if it might be more appropriate to turn it on in development and preview environments only. +## Agumenting SvelteKit's builtin tracing + +SvelteKit provides access to the `root` span and the `current` span on the request event. The root span is the one associated with your root `handle` function, and the current span could be associated with `handle`, `load`, a form action, or a remote function, depending on the context. You can annotate these spans with any attributes you wish to record: + +```js +/// file: $lib/authenticate.ts +async function authenticate() { + const event = getRequestEvent(); + const user = await getAuthenticatedUser(event); + event.tracing.root.setAttribute({ userId: user.id }); +} +``` + ## Development quickstart To view your first trace, you'll need to set up a local collector. We'll use [Jaeger](https://www.jaegertracing.io/docs/getting-started/) in this example, as they provide an easy-to-use quickstart command. Once your collector is running locally: From 477e50ea884837435344c10421393972cbdde8b4 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 14 Aug 2025 15:54:19 -0600 Subject: [PATCH 73/74] fix --- documentation/docs/30-advanced/68-observability.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/docs/30-advanced/68-observability.md b/documentation/docs/30-advanced/68-observability.md index db85b4262fb8..047726aa2371 100644 --- a/documentation/docs/30-advanced/68-observability.md +++ b/documentation/docs/30-advanced/68-observability.md @@ -46,7 +46,7 @@ SvelteKit provides access to the `root` span and the `current` span on the reque async function authenticate() { const event = getRequestEvent(); const user = await getAuthenticatedUser(event); - event.tracing.root.setAttribute({ userId: user.id }); + event.tracing.root.setAttribute('userId', user.id); } ``` From ab91eed8022feb62d50d679aa898f0df59897da1 Mon Sep 17 00:00:00 2001 From: "S. Elliott Johnson" Date: Thu, 14 Aug 2025 16:37:41 -0600 Subject: [PATCH 74/74] fix --- packages/kit/test/apps/basics/svelte.config.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/kit/test/apps/basics/svelte.config.js b/packages/kit/test/apps/basics/svelte.config.js index 43cac801aa24..d9772c05b5d1 100644 --- a/packages/kit/test/apps/basics/svelte.config.js +++ b/packages/kit/test/apps/basics/svelte.config.js @@ -5,7 +5,15 @@ const config = { kit: { adapter: { name: 'test-adapter', - adapt() {}, + adapt(builder) { + builder.instrument({ + entrypoint: `${builder.getServerDirectory()}/index.js`, + instrumentation: `${builder.getServerDirectory()}/instrumentation.server.js`, + module: { + exports: ['Server'] + } + }); + }, emulate() { return { platform({ config, prerender }) {